【问题标题】:Can't find the correct SQL function ( SUM/COUNT - LEFT JOIN )找不到正确的 SQL 函数(SUM/COUNT - LEFT JOIN)
【发布时间】:2021-01-04 02:52:00
【问题描述】:

我对 SQL 函数的问题是,我经常混合使用 SUM / COUNT,甚至可以在其中放置 WHERE 子句和 GROUP BY 的简短版本,SQL 是我的缺陷之一。

好的,现在这是我当前的问题,我需要创建一个 SQL 函数(在我的 PHP 模型中)来获取我“今天”的订单数量及其总成本,但我需要按国家/地区分隔结果(对不起我的英语),例如我想要的结果应该是这样的(假设我今天有 20 个订单):
美国:15 个订单(共 288 美元),加拿大:5 个订单(共 94 美元)

我尝试了很多东西,唯一没有给我错误的两个是这两个(但与我需要的结果相去甚远):

SELECT sum(o.amount) AS totalmoney, p.name, p.id, p.name_clean, p.iso_code 
FROM orders AS o 
LEFT JOIN customers AS c ON o.id_customer = c.id 
LEFT JOIN countries AS p ON c.country = p.id    
WHERE DATE(o.date_create) = CURDATE()

SELECT sum(o.amount) AS totalmoney, o.date_create, p.name, COUNT(p.id) AS totalpays,
p.name_clean, p.iso_code, c.country 
FROM orders AS o 
LEFT JOIN customers AS c ON o.id_customer = c.id 
LEFT JOIN countries AS p ON c.country = p.id 
GROUP BY o.date_create

我的三个表是(表名:列有用):

国家:id - 名称

客户:id - country_id

订单:id - id_customer - 金额 ($) - date_create

你能帮帮我吗?

感谢您的宝贵时间。

------------- 使用我使用的答案进行编辑 ---------------

感谢所有参与并帮助我更好地理解 SQL 的人。

SELECT sum(orders.amount) total, countries.name
FROM orders 
INNER JOIN customers ON orders.id_customer = customers.id
INNER JOIN countries ON countries.id = customers.country_id
WHERE orders.date_create = ?
GROUP BY customers.id

这正是我需要的。

【问题讨论】:

  • 能否请您提供三个表格的完整结构和一些示例数据以供我们使用,以便我们更清楚地了解情况并更好地帮助您?

标签: php mysql sql


【解决方案1】:

您想在某个日期按国家/地区分组,因此您的分组依据是国家,日期是哪里:


SELECT sum(orders.amount) total, countries.name
FROM orders 
INNER JOIN customers ON orders.id_customer = customers.id
INNER JOIN countries ON countries.id = customers.country_id
WHERE orders.date_create = ?
GROUP BY customers.id

这里适合使用内部连接,因为连接应该只为每个订单的客户和国家/地区生成一行。

【讨论】:

  • 谢谢,这正是我所需要的,我在使用 INNER JOIN / LEFT JOIN 等方面遇到了困难。我非常需要处理我的 SQL,感谢大家的所有回答。跨度>
【解决方案2】:

尝试一下: -- PostgreSQL

drop table orders;
drop table countries;
drop table customers;

CREATE TABLE countries
(
    id   integer not null,
    name varchar(200)
);

insert into countries(id, name) values (1, 'MEXICO');
insert into countries(id, name) values (2, 'US');
insert into countries(id, name) values (3, 'CANADA');

create table customers
(
    id   integer not null,
    name varchar(200),
    country integer not null
);

insert into customers(id, name, country) values (1, 'Huey',1);
insert into customers(id, name, country) values (2, 'Dewey',2);
insert into customers(id, name, country) values (3, 'Louie',3);

create table orders
(
    id          integer not null,
    id_customer integer not null,
    amount      double precision,
    date_create date
);

insert into orders values (1, 1,  500.0, '20200103');
insert into orders values (2, 1,  1000, '20200103');
insert into orders values (3, 2, 500, '20200103');
insert into orders values (4, 3, 500, '20200103');
insert into orders values (5, 1,  500, '20200103');

SELECT COUNT(*) AS num_orders,  sum(o.amount) AS totalmoney, p.name
FROM orders AS o
         INNER JOIN customers AS c ON o.id_customer = c.id
         INNER JOIN countries AS p ON c.country = p.id
WHERE DATE(o.date_create) = '20200103'
 group by   p.name
order by num_orders desc;

【讨论】:

  • 干得好,显示示例数据。我建议对主键进行分组,但这应该可以正常工作。
【解决方案3】:

您可以使用oversumcount

select sum(amount) over(partition by contry_id) as totalamount,
       count(contry_id) over(partition by contry_id) as totalcount,
       name, ord.id 
from orders ord left join customers cus on ord.customer_id = cus.id
                left join countries con on cus.contry_id = con.id
where date_create = [date]  --using string as a pseudo date when testing, so change is needed

这是一个带有一些伪数据的db<>fiddle

这还将按创建日期获取与 OP 匹配的数据组,需要更多 imo。

select distinct sum(amount) over(partition by contry_id,date_create) as totalamount,
       count(contry_id) over(partition by contry_id,date_create) as totalcount,
       name, date_create
from orders ord left join customers cus on ord.customer_id = cus.id
                left join countries con on cus.contry_id = con.id

具有窗口函数的优点:over 是您可以使用具有不同“条件”的不同聚合函数,并且不需要 group by 每个非聚合列,这通常会导致很多子查询。

【讨论】:

  • 谢谢,这将有助于我更好地理解 SQL
【解决方案4】:

这应该做你想做的事:

SELECT 
    c.name,
    sq.totalmoney
FROM
    countries as c
JOIN
    (SELECT 
        SUM(o.amount) AS totalmoney,
        c.id
    FROM
        (SELECT 
            *
        FROM 
            orders 
        WHERE 
            DATE(date_create) = CURDATE()
        ) AS o 
    JOIN 
        customers AS c 
    ON 
        o.id_customer = c.id
    GROUP BY c.id) AS sq
on c.id = sq.id;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-06-10
    • 1970-01-01
    • 2010-10-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多