SQL SELECT分组按一列显示最近未找到的日期

时间:2015-10-19 14:00:13

标签: mysql sql select group-by distinct

我有一张这样的表

ID  | DrugstoreName  | date       | city      | zipcode
1   | a1             | 2015-10-19 | paris 01  | 75001
2   | a2             | 2015-10-23 | paris 02  | 75002
3   | a3             | 2015-10-19 | paris 05  | 75005
4   | a4             | 2015-10-24 | marseille | 13000
5   | a5             | 2015-10-19 | nice      | 06000
6   | a6             | 2015-10-23 | paris 09  | 75009
7   | a7             | 2015-10-24 | paris 09  | 75009
8   | a8             | 2015-10-24 | paris 03  | 75003
9   | a9             | 2015-10-23 | paris 03  | 75003
10  | a10            | 2015-10-19 | paris 04  | 75004

我要做的是从我的表中选择不同的(城市/邮政编码),我没有任何匹配记录,至少有一个特定日期(date1,date2,date3)。

如果可能的话,还会显示我们没有记录的最近日期。

例如我想选择distinct(city,zipcode,nearest-date-not-found)WHERE日期与(“2015-10-23”,“2015-10-24”)中的至少一个不匹配; 结果应该是:

paris 01   | 75001 | 2015-10-23
paris 02   | 75002 | 2015-10-24
paris 05   | 75005 | 2015-10-23
marseille  | 13000 | 2015-10-23
nice       | 06000 | 2015-10-23
paris 04   | 75004 | 2015-10-23

这有点复杂,我知道我应该考虑重新设计我的桌子。但这就是我现在所拥有的,我应该处理它。

1 个答案:

答案 0 :(得分:0)

这里的诀窍是你想要缺少记录的日期。那么当数据不存在时,如何从数据库中选择数据呢?我们需要创建那些丢失的记录,以便数据库将它们作为值返回。

在下面的示例中,我们通过交叉连接到包含要限制的日期的派生表(Y)来完成此操作。这也可以通过使用SELECT Distinct date from Foo where date in ('2015-10-23','2015-10-24')来完成,假设这些日期存在记录。然后,通过使用聚合函数,不同的on日期和having子句,我们可以生成所需的结果。

外部联接不起作用。它不会为每个城市/拉链生成日期只有空记录。因此,这成为了解交叉连接以及笛卡尔产品为何可以提供帮助的好时机。

我使用group_concat来显示所有缺少的日期和记录日期。我做了这个,所以你可以看到为什么min(Y.date)返回最低日期。

SELECT A.city, A.zipcode, min(Y.date) as Date, 
group_Concat(Y.Date) as AllMissingDates,
group_Concat(A.Date) as RecordDates
FROM foo A
CROSS JOIN 
 (SELECT '2015-10-23' date UNION ALL SELECT '2015-10-24') Y
WHERE A.Date <> Y.date
GROUP BY City, ZipCode
Having count(Distinct A.Date) < 2;

SQL FIDDLE

**city      zipCode Date        AllMissingDates  RecordDates**
marseille   13000   2015-10-23  2015-10-23       2015-10-24
nice        6000    2015-10-23  2015-10-24,      2015-10-19,
                                2015-10-23       2015-10-19
paris 01    75001   2015-10-23  2015-10-23,      2015-10-19,
                                2015-10-24       2015-10-19
paris 02    75002   2015-10-24  2015-10-24       2015-10-23
paris 04    75004   2015-10-23  2015-10-24,      2015-10-19,
                                2015-10-23       2015-10-19
paris 05    75005   2015-10-23  2015-10-23,      2015-10-19,
                                2015-10-24       2015-10-19