使用日期序列表过滤加入

时间:2018-02-08 19:29:06

标签: mysql

编辑:请参阅下面的第3个SQL示例以及子查询。它产生了所需的结果:在class.level上过滤=没有日期间隔。但是,它看起来不是一个非常有效的查询。

我使用预先填写的日期序列表并将其连接到事件表中以填充空白"在活动日期之间。事件表与events.class_id = classs.id上的类表有关,以引入类信息。

为了过滤类col并保留日期序列,我必须将class col条件放在事件中,类连接如下。 这可以工作,但事件记录仍然返回null类名。黄色突出好,红色突出不亮。希望得到相同的结果,但没有红色的事件记录

enter image description here

CREATE TABLE `date_sequence` (
   date_ date NOT NULL
)

CREATE TABLE `events` (
  id int(10) UNSIGNED NOT NULL,
  class_id mediumint(8) UNSIGNED NOT NULL,
  start_dt datetime DEFAULT NULL,
  end_dt datetime DEFAULT NULL,
) 

CREATE TABLE `classes` (
  id int(10) UNSIGNED NOT NULL,
  name varchar(48) NOT NULL,
  level tinyint(4) NOT NULL,
) 




// regular select, no filter
SELECT
c.name,
e.id AS event_id,
e.class_id AS class_id,
e.start_dt,
ds.date_ AS `date`,
FROM date_sequence ds 
LEFT JOIN events e ON DATE(e.start_dt) = ds.date_ 
LEFT JOIN classes c ON e.class_id =c.id
WHERE  ds.date_ >= '2018-04-01' AND  ds.date_ < '2018-05-01'
ORDER BY ds.date_, e.start_dt



// with filter on class.level = 2  has gaps
SELECT
c.name,
e.id AS event_id,
e.class_id AS class_id,
e.start_dt,
ds.date_ AS `date`,
FROM date_sequence ds 
LEFT JOIN events e ON DATE(e.start_dt) = ds.date_ 
LEFT JOIN classes c ON e.class_id =c.id AND c.level = 2
WHERE  ds.date_ >= '2018-04-01' AND  ds.date_ < '2018-05-01'
ORDER BY ds.date_, e.start_dt




// No gaps
SELECT
B.name,
B.level,
B.id AS event_id,
B.class_id AS class_id,
B.start_dt,
ds.date_ AS `date`,
FROM date_sequence ds 
LEFT JOIN 
(SELECT events.*, c.name, c.level
 FROM events 
 LEFT JOIN classes c ON events.class_id = c.id
 WHERE c.level=1
) 
AS B ON  ds.date_ = DATE(B.start_dt)
WHERE  ds.date_ >= '2018-06-01' AND ds.date_ < '2018-07-01'
ORDER BY ds.date_, B.start_dt

1 个答案:

答案 0 :(得分:0)

您需要在查询中添加HAVING条件,并根据现有或不存在的类ID创建条件。首先将此部分添加到您的选择中: SELECT c.name, c.id as cid, e.id AS event_id,

请参阅,我添加了c.id as cid,以便能够在HAVING

中使用它

然后就在WHERE陈述之后:

WHERE ds.date_ >= '2018-04-01' AND ds.date_ < '2018-05-01' HAVING ((cid IS NULL AND event_id IS NULL) or cid IS NOT NULL) ORDER BY ds.date_, e.start_dt

因此整个SQL查询如下所示:

SELECT c.name, c.id as cid, e.id AS event_id, e.class_id AS class_id, e.start_dt, ds.date_ AS日期FROM date_sequence ds LEFT JOIN events e ON DATE(e.start_dt) = ds.date_ LEFT JOIN classes c ON e.class_id =c.id AND c.level = 2 WHERE ds.date_ >= '2018-04-01' AND ds.date_ < '2018-05-01' HAVING ((cid IS NULL AND event_id IS NULL) or cid IS NOT NULL) ORDER BY ds.date_, e.start_dt