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

SQL SELECT group by one column and show nearest not found date

我有一个table这样的

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

我想做的是 select 与我的 table 不同(city/zipcode),为此我没有任何匹配的记录至少有一个特定的日期(日期 1、日期 2、日期 3)。

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

例如我想 select 不同的(城市、邮政编码、最近未找到的日期)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

有点复杂,我知道我应该考虑重新设计我的 table。但这是我目前所拥有的,我应该处理它。

这里的诀窍是您需要丢失记录的日期。那么当数据不存在时,您如何 select 来自数据库的数据呢?我们需要创建那些缺失的记录,以便数据库将它们 return 作为一个值。

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

外连接不起作用。它不会为每个 city/zips 只生成一个空记录的日期。因此,现在是了解交叉连接以及笛卡尔乘积为何有用的好时机。

我用group_concat来显示所有缺失的日期和记录日期。我这样做是为了让您明白为什么 min(Y.date) returns 是最低日期。

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