在 SQL 中,如果满足条件,我如何用 child 记录过滤 parent
In SQL, how do I filter a parent with its child records if either satisfies a condition
我有以下 table 作为示例。对于 parent 和 child 记录,我只想检索 ScheduleDate 小于 2022-01-03(2022 年 1 月 3 日)的记录,但我只想要整个家庭(parents 和 children 在一起)。使用这组记录,结果应该 return 只有记录 1 到 9。 ScheduleId 12不满足条件,与10、13有关系。10与11有关系。
DROP TABLE IF EXISTS #MySchedule;
CREATE TABLE #MySchedule (ScheduleId INT, ParentScheduleId INT, ScheduleDate DATETIME2);
INSERT #MySchedule (ScheduleId, ParentScheduleId, ScheduleDate) VALUES (1,NULL,'2022-01-01');
INSERT #MySchedule (ScheduleId, ParentScheduleId, ScheduleDate) VALUES (2,NULL,'2022-01-01');
INSERT #MySchedule (ScheduleId, ParentScheduleId, ScheduleDate) VALUES (3,2,'2022-01-01');
INSERT #MySchedule (ScheduleId, ParentScheduleId, ScheduleDate) VALUES (4,2,'2022-01-01');
INSERT #MySchedule (ScheduleId, ParentScheduleId, ScheduleDate) VALUES (5,4,'2022-01-01');
INSERT #MySchedule (ScheduleId, ParentScheduleId, ScheduleDate) VALUES (6,NULL,'2022-01-01');
INSERT #MySchedule (ScheduleId, ParentScheduleId, ScheduleDate) VALUES (7,6,'2022-01-01');
INSERT #MySchedule (ScheduleId, ParentScheduleId, ScheduleDate) VALUES (8,6,'2022-01-01');
INSERT #MySchedule (ScheduleId, ParentScheduleId, ScheduleDate) VALUES (9,8,'2022-01-02');
INSERT #MySchedule (ScheduleId, ParentScheduleId, ScheduleDate) VALUES (10,NULL,'2022-01-02');
INSERT #MySchedule (ScheduleId, ParentScheduleId, ScheduleDate) VALUES (11,10,'2022-01-02');
INSERT #MySchedule (ScheduleId, ParentScheduleId, ScheduleDate) VALUES (12,10,'2022-01-03');
INSERT #MySchedule (ScheduleId, ParentScheduleId, ScheduleDate) VALUES (13,12,'2022-01-02');
INSERT #MySchedule (ScheduleId, ParentScheduleId, ScheduleDate) VALUES (14,NULL,'2022-01-03');
INSERT #MySchedule (ScheduleId, ParentScheduleId, ScheduleDate) VALUES (15,NULL,'2022-01-03');
INSERT #MySchedule (ScheduleId, ParentScheduleId, ScheduleDate) VALUES (16,NULL,'2022-01-04');
INSERT #MySchedule (ScheduleId, ParentScheduleId, ScheduleDate) VALUES (17,16,'2022-01-04');
我必须说你的问题定义有点含糊。在编写此解决方案时,我不得不假设您希望看到一个没有 children 的家庭 ScheduleDate 大于 2022-01 -03。如果这不是您要寻找的解决方案,请澄清您的问题定义。
我们开始吧:D
DROP TABLE IF EXISTS #MySchedule;
CREATE TABLE #MySchedule (ScheduleId INT, ParentScheduleId INT, ScheduleDate DATETIME2);
INSERT #MySchedule (ScheduleId, ParentScheduleId, ScheduleDate) VALUES (1,NULL,'2022-01-01');
INSERT #MySchedule (ScheduleId, ParentScheduleId, ScheduleDate) VALUES (2,NULL,'2022-01-01');
INSERT #MySchedule (ScheduleId, ParentScheduleId, ScheduleDate) VALUES (3,2,'2022-01-01');
INSERT #MySchedule (ScheduleId, ParentScheduleId, ScheduleDate) VALUES (4,2,'2022-01-01');
INSERT #MySchedule (ScheduleId, ParentScheduleId, ScheduleDate) VALUES (5,4,'2022-01-01');
INSERT #MySchedule (ScheduleId, ParentScheduleId, ScheduleDate) VALUES (6,NULL,'2022-01-01');
INSERT #MySchedule (ScheduleId, ParentScheduleId, ScheduleDate) VALUES (7,6,'2022-01-01');
INSERT #MySchedule (ScheduleId, ParentScheduleId, ScheduleDate) VALUES (8,6,'2022-01-01');
INSERT #MySchedule (ScheduleId, ParentScheduleId, ScheduleDate) VALUES (9,8,'2022-01-02');
INSERT #MySchedule (ScheduleId, ParentScheduleId, ScheduleDate) VALUES (10,NULL,'2022-01-02');
INSERT #MySchedule (ScheduleId, ParentScheduleId, ScheduleDate) VALUES (11,10,'2022-01-02');
INSERT #MySchedule (ScheduleId, ParentScheduleId, ScheduleDate) VALUES (12,10,'2022-01-03');
INSERT #MySchedule (ScheduleId, ParentScheduleId, ScheduleDate) VALUES (13,12,'2022-01-02');
INSERT #MySchedule (ScheduleId, ParentScheduleId, ScheduleDate) VALUES (14,NULL,'2022-01-03');
INSERT #MySchedule (ScheduleId, ParentScheduleId, ScheduleDate) VALUES (15,NULL,'2022-01-03');
INSERT #MySchedule (ScheduleId, ParentScheduleId, ScheduleDate) VALUES (16,NULL,'2022-01-04');
INSERT #MySchedule (ScheduleId, ParentScheduleId, ScheduleDate) VALUES (17,16,'2022-01-04');
DECLARE @date DATETIME2 = '2022-01-03';
SELECT COUNT(1) FROM #MySchedule;
WITH src AS (
/* get all ultimate parents */
SELECT ScheduleId,
[ParentScheduleId],
ScheduleDate,
ScheduleId [ultimate_ParentScheduleId]
FROM #MySchedule shd
WHERE shd.ParentScheduleId IS NULL
UNION ALL
SELECT shd.ScheduleId,
shd.ParentScheduleId,
shd.ScheduleDate,
src.ultimate_ParentScheduleId
FROM #MySchedule shd
JOIN src
ON shd.ParentScheduleId = src.ScheduleId
)
SELECT
src.ultimate_ParentScheduleId,
src.ParentScheduleId,
src.ScheduleId,
src.ScheduleDate
FROM src
JOIN (
SELECT src.ultimate_ParentScheduleId
FROM src
GROUP BY src.ultimate_ParentScheduleId
HAVING MAX(src.ScheduleDate) < @date
) gp
ON gp.ultimate_ParentScheduleId = src.ultimate_ParentScheduleId
ORDER BY src.ultimate_ParentScheduleId, COALESCE(src.ParentScheduleId, src.ScheduleId), src.ScheduleId
;
我有以下 table 作为示例。对于 parent 和 child 记录,我只想检索 ScheduleDate 小于 2022-01-03(2022 年 1 月 3 日)的记录,但我只想要整个家庭(parents 和 children 在一起)。使用这组记录,结果应该 return 只有记录 1 到 9。 ScheduleId 12不满足条件,与10、13有关系。10与11有关系。
DROP TABLE IF EXISTS #MySchedule;
CREATE TABLE #MySchedule (ScheduleId INT, ParentScheduleId INT, ScheduleDate DATETIME2);
INSERT #MySchedule (ScheduleId, ParentScheduleId, ScheduleDate) VALUES (1,NULL,'2022-01-01');
INSERT #MySchedule (ScheduleId, ParentScheduleId, ScheduleDate) VALUES (2,NULL,'2022-01-01');
INSERT #MySchedule (ScheduleId, ParentScheduleId, ScheduleDate) VALUES (3,2,'2022-01-01');
INSERT #MySchedule (ScheduleId, ParentScheduleId, ScheduleDate) VALUES (4,2,'2022-01-01');
INSERT #MySchedule (ScheduleId, ParentScheduleId, ScheduleDate) VALUES (5,4,'2022-01-01');
INSERT #MySchedule (ScheduleId, ParentScheduleId, ScheduleDate) VALUES (6,NULL,'2022-01-01');
INSERT #MySchedule (ScheduleId, ParentScheduleId, ScheduleDate) VALUES (7,6,'2022-01-01');
INSERT #MySchedule (ScheduleId, ParentScheduleId, ScheduleDate) VALUES (8,6,'2022-01-01');
INSERT #MySchedule (ScheduleId, ParentScheduleId, ScheduleDate) VALUES (9,8,'2022-01-02');
INSERT #MySchedule (ScheduleId, ParentScheduleId, ScheduleDate) VALUES (10,NULL,'2022-01-02');
INSERT #MySchedule (ScheduleId, ParentScheduleId, ScheduleDate) VALUES (11,10,'2022-01-02');
INSERT #MySchedule (ScheduleId, ParentScheduleId, ScheduleDate) VALUES (12,10,'2022-01-03');
INSERT #MySchedule (ScheduleId, ParentScheduleId, ScheduleDate) VALUES (13,12,'2022-01-02');
INSERT #MySchedule (ScheduleId, ParentScheduleId, ScheduleDate) VALUES (14,NULL,'2022-01-03');
INSERT #MySchedule (ScheduleId, ParentScheduleId, ScheduleDate) VALUES (15,NULL,'2022-01-03');
INSERT #MySchedule (ScheduleId, ParentScheduleId, ScheduleDate) VALUES (16,NULL,'2022-01-04');
INSERT #MySchedule (ScheduleId, ParentScheduleId, ScheduleDate) VALUES (17,16,'2022-01-04');
我必须说你的问题定义有点含糊。在编写此解决方案时,我不得不假设您希望看到一个没有 children 的家庭 ScheduleDate 大于 2022-01 -03。如果这不是您要寻找的解决方案,请澄清您的问题定义。 我们开始吧:D
DROP TABLE IF EXISTS #MySchedule;
CREATE TABLE #MySchedule (ScheduleId INT, ParentScheduleId INT, ScheduleDate DATETIME2);
INSERT #MySchedule (ScheduleId, ParentScheduleId, ScheduleDate) VALUES (1,NULL,'2022-01-01');
INSERT #MySchedule (ScheduleId, ParentScheduleId, ScheduleDate) VALUES (2,NULL,'2022-01-01');
INSERT #MySchedule (ScheduleId, ParentScheduleId, ScheduleDate) VALUES (3,2,'2022-01-01');
INSERT #MySchedule (ScheduleId, ParentScheduleId, ScheduleDate) VALUES (4,2,'2022-01-01');
INSERT #MySchedule (ScheduleId, ParentScheduleId, ScheduleDate) VALUES (5,4,'2022-01-01');
INSERT #MySchedule (ScheduleId, ParentScheduleId, ScheduleDate) VALUES (6,NULL,'2022-01-01');
INSERT #MySchedule (ScheduleId, ParentScheduleId, ScheduleDate) VALUES (7,6,'2022-01-01');
INSERT #MySchedule (ScheduleId, ParentScheduleId, ScheduleDate) VALUES (8,6,'2022-01-01');
INSERT #MySchedule (ScheduleId, ParentScheduleId, ScheduleDate) VALUES (9,8,'2022-01-02');
INSERT #MySchedule (ScheduleId, ParentScheduleId, ScheduleDate) VALUES (10,NULL,'2022-01-02');
INSERT #MySchedule (ScheduleId, ParentScheduleId, ScheduleDate) VALUES (11,10,'2022-01-02');
INSERT #MySchedule (ScheduleId, ParentScheduleId, ScheduleDate) VALUES (12,10,'2022-01-03');
INSERT #MySchedule (ScheduleId, ParentScheduleId, ScheduleDate) VALUES (13,12,'2022-01-02');
INSERT #MySchedule (ScheduleId, ParentScheduleId, ScheduleDate) VALUES (14,NULL,'2022-01-03');
INSERT #MySchedule (ScheduleId, ParentScheduleId, ScheduleDate) VALUES (15,NULL,'2022-01-03');
INSERT #MySchedule (ScheduleId, ParentScheduleId, ScheduleDate) VALUES (16,NULL,'2022-01-04');
INSERT #MySchedule (ScheduleId, ParentScheduleId, ScheduleDate) VALUES (17,16,'2022-01-04');
DECLARE @date DATETIME2 = '2022-01-03';
SELECT COUNT(1) FROM #MySchedule;
WITH src AS (
/* get all ultimate parents */
SELECT ScheduleId,
[ParentScheduleId],
ScheduleDate,
ScheduleId [ultimate_ParentScheduleId]
FROM #MySchedule shd
WHERE shd.ParentScheduleId IS NULL
UNION ALL
SELECT shd.ScheduleId,
shd.ParentScheduleId,
shd.ScheduleDate,
src.ultimate_ParentScheduleId
FROM #MySchedule shd
JOIN src
ON shd.ParentScheduleId = src.ScheduleId
)
SELECT
src.ultimate_ParentScheduleId,
src.ParentScheduleId,
src.ScheduleId,
src.ScheduleDate
FROM src
JOIN (
SELECT src.ultimate_ParentScheduleId
FROM src
GROUP BY src.ultimate_ParentScheduleId
HAVING MAX(src.ScheduleDate) < @date
) gp
ON gp.ultimate_ParentScheduleId = src.ultimate_ParentScheduleId
ORDER BY src.ultimate_ParentScheduleId, COALESCE(src.ParentScheduleId, src.ScheduleId), src.ScheduleId
;