首页 > 解决方案 > 是否可以在一个查询中获取所需的数据?

问题描述

我有一个包含门票的数据库。每张票都有一个唯一编号,但该编号在表中不是唯一的。因此,例如票 #1000 可以在表中与不同的其他列多次出现(我在此处删除了该列作为示例)。

create table countries
(
   isoalpha varchar(2),
   pole varchar(50)
);

insert into countries values ('DE', 'EMEA'),('FR', 'EMEA'),('IT', 'EMEA'),('US','USCAN'),('CA', 'USCAN');

create table tickets 
(
  id int primary key auto_increment,
  number int,
  isoalpha varchar(2),
  created datetime 
);

insert into tickets (number, isoalpha, created) values
(1000, 'DE', '2021-01-01 00:00:00'),
(1001, 'US', '2021-01-01 00:00:00'),
(1002, 'FR', '2021-01-01 00:00:00'),
(1003, 'CA', '2021-01-01 00:00:00'),
(1000, 'DE', '2021-01-01 00:00:00'),
(1000, 'DE', '2021-01-01 00:00:00'),
(1004, 'DE', '2021-01-02 00:00:00'),
(1001, 'US', '2021-01-01 00:00:00'),
(1002, 'FR', '2021-01-01 00:00:00'),
(1005, 'IT', '2021-01-02 00:00:00'),
(1006, 'US', '2021-01-02 00:00:00'),
(1007, 'DE', '2021-01-02 00:00:00');

这是一个例子:

http://sqlfiddle.com/#!9/3f4ba4/6

我需要输出的是每天新创建的票的数量,分为来自 USCAN 和世界其他地区的票。

所以对于这个例子,输出的数据应该是

Date | USCAN | Other
'2021-01-01' | 2 | 2
'2021-01-02' | 1 | 3

目前我使用这两个查询来获取所有新票,然后在我的应用程序代码中添加具有相同日期的行数:

SELECT MIN(ti.created) AS date
        FROM tickets ti
        LEFT JOIN countries ct ON (ct.isoalpha = ti.isoalpha)
        WHERE ct.pole = 'USCAN'
        GROUP BY ti.number
        ORDER BY date

SELECT MIN(ti.created) AS date
        FROM tickets ti
        LEFT JOIN countries ct ON (ct.isoalpha = ti.isoalpha)
        WHERE ct.pole <> 'USCAN'
        GROUP BY ti.number
        ORDER BY date

但这看起来不是一个非常干净的方法。那么如何改进查询以减少开销来获取所需的数据呢?

推荐使用 mySQL 5.7 的 Ii

标签: mysql

解决方案


您可以使用条件聚合在逻辑上组合查询:

SELECT
    MIN(CASE WHEN ct.pole = 'USCAN'  THEN ti.created END) AS date_uscan,
    MIN(CASE WHEN ct.pole <> 'USCAN' THEN ti.created END) AS date_other
FROM tickets ti
LEFT JOIN countries ct ON ct.isoalpha = ti.isoalpha
GROUP BY ti.number
ORDER BY date;

推荐阅读