SQL:根据相关表

时间:2017-08-29 01:47:09

标签: mysql sql

我有两张桌子;

国家/地区(ID,名称,地区);

1, 'UK', '1';
2, 'USA', '1';
3, 'AUSTRALIA', '1';
4, 'CHINA', '0';
5, 'INDIA', '0';
6, 'SRI LANKA', '0' ;

门票(id,country_id,issued_date,持有人,性别,费用,已取消);

100, 2, 2017-08-15, 'Person 1', 'M', 200, '1';
101, 2, 2017-08-15, 'Person 2', 'M', 200, '0';
103, 3, 2017-08-15, 'Person 3', 'M', 200, '0';
104, 5, 2017-08-16, 'Person 1', 'M', 200, '0';
105, 6, 2017-08-16, 'Person 1', 'M', 200, '0';
106, 1, 2017-08-17, 'Person 1', 'M', 200, '0';
107, 3, 2017-08-18, 'Person 1', 'M', 200, '1';
108, 4, 2017-08-18, 'Person 1', 'M', 200, '0';

我想基于issued_date将所有故障单与一些聚合字段分组以生成摘要。这是我的问题: -

SELECT

issued_date,
COUNT(*) as total_tickets,
COUNT(CASE WHEN canceled = '0' THEN 1 ELSE NULL END) as issued_tickets,
SUM(CASE WHEN canceled = '0' THEN fee ELSE NULL END) as total_amount

FROM tickets

GROUP BY issued_date;

但是,如何在相关的表国家/地区使用COUNT和SUM?例如,我想显示一个日期(2017-08-15)从一个地区=' 1'出售的门票数量。

我尝试了以下操作,但对于region_1字段的结果不正确

SELECT

issued_date,
COUNT(*) as total_tickets,
COUNT(CASE WHEN canceled = '0' THEN 1 ELSE NULL END) as issued_tickets,SUM(CASE WHEN canceled = '0' THEN fee ELSE NULL END) as total_amount,
(SELECT COUNT(countries.id) FROM countries WHERE countries.id = tickets.country_id && countries.region = '1') as region_1

FROM tickets

GROUP BY issued_date;

3 个答案:

答案 0 :(得分:0)

我将使用在issue_date,country_id和region上分组的派生表,并在内部联接中使用该派生表。

SELECT issued_date
    ,COUNT(*) AS total_tickets
    ,COUNT(CASE WHEN canceled = '0' THEN 1 ELSE NULL END) AS issued_tickets
    ,SUM(CASE WHEN canceled = '0' THEN fee ELSE NULL END) AS total_amount
    ,tickets_by_region.total_region_1_tickets
FROM tickets
INNER JOIN (
    SELECT issued_date
        ,country_id
        ,countries.region
        ,COUNT(*) AS total_region_1_tickets
    FROM tickets
    INNER JOIN countries ON (countries.id = tickets.country_id)
    GROUP BY issued_date
        ,countries.country_id
        ,countries.region
    ) tickets_by_region ON (
        tickets_by_region.issued_date = tickets.issued_date
        AND tickets_by_region.country_id = tickets.country_id
        AND tickets_by_region.region = '1'
        ) AS region_1
GROUP BY issued_date;

HTH。

答案 1 :(得分:0)

您可能需要使用INNER JOINGROUP BY with HAVING,它们允许在相关键上附加下一个表,并添加您需要使用它们的其他摘要或计数,例如子查询,因为它们需要使用否过滤数据。

  

方法是在子查询中准备数据,然后加入过滤后的数据   到主表,可以对最终结果进行最终过滤。

SQL看起来像波纹管(在本地测试)

SELECT t1.issued_date, COUNT(t1.id) as sum_tickets, t2.region, t3.total_tickets
FROM tickets t1
LEFT JOIN (SELECT id, COUNT(id) as total_tickets FROM tickets) t3 ON t3.id = t1.id
INNER JOIN countries t2 ON t2.id = t1.country_id
GROUP BY t1.issued_date
HAVING (t2.region = '1')


输出

issued_date,sum_tickets,region,total_tickets
2017-08-15,3,1,8 2017-08-17,1,1,null
2017-08-18,2,1,null

您可以在查询中为HAVING添加更多条件。

答案 2 :(得分:0)

我只会使用带有JOIN的条件聚合:

SELECT t.issued_date, COUNT(*) as total_tickets,
       SUM(t.canceled = 0) as issued_tickets,
       SUM(CASE WHEN t.canceled = 0 THEN t.fee END) as total_amount,
       SUM(c.region = 1) as num_region_1
FROM tickets t JOIN
     countries c
     ON t.country_id = c.id
GROUP BY t.issued_date;