我有一张这样的表
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
这有点复杂,我知道我应该考虑重新设计我的桌子。但这就是我现在所拥有的,我应该处理它。
答案 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;
**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