我把这个问题的大部分都放下了,直到新的情况出现并且让我感到困惑。给出以下简化表模式:
父表:
ID
FName
LName
子表:
[Index]
ParentID
Active_Flag
ExpirationDate
我想要做的是获取父行:
我的前两个标准提出了以下查询:
SELECT p.ID, p.LNAME, p.FNAME,
CASE
WHEN COUNT(ct.indx) = 0 THEN 'None'
WHEN ct.ExpirationDate is NULL or ct.ExpirationDate = '' THEN 'No expiration date'
END AS Issue
FROM ParentTable AS p
LEFT JOIN ChildTable ct
ON p.ID = ct.ParentID
GROUP BY p.ID, p.LNAME, p.FNAME, ct.[INDEX], ct.ExpirationDate
HAVING (COUNT(ct.[INDEX]) = 0) OR (ct.ExpirationDate IS NULL OR ct.ExpirationDate = '')
ORDER BY p.LNAME
我不知道如何解释#3。任何帮助表示赞赏。提前谢谢。
答案 0 :(得分:2)
您也可以在HAVING子句中执行此操作:
SELECT p.ID, p.LNAME, p.FNAME,
(CASE WHEN COUNT(ct.indx) = 0 THEN 'None'
WHEN ct.ExpirationDate is NULL or ct.ExpirationDate = '' THEN 'No expiration date'
WHEN sum(case when ActiveFlag = 1 then 1 else 0 end) = 0 then 'No active children'
END) AS Issue
FROM ParentTable p LEFT JOIN
ChildTable c
ON p.ID = ct.ParentID
GROUP BY p.ID, p.LNAME, p.FNAME
HAVING (COUNT(ct.[INDEX]) = 0) OR
(ct.ExpirationDate IS NULL OR ct.ExpirationDate = '') or
sum(case when ActiveFlag = 1 then 1 else 0 end) = 0
ORDER BY p.LNAME
SELECT中的DISTINCT是多余的。你不需要聚合。
如果activeFlag确实是一个整数,你可以简化必须“sum(ActiveFlag)”。如果没有,那么它应该是“='1'”而不是“= 1”。
答案 1 :(得分:0)
您可以使用工会进行此查询..... 我不确定这个问题....但它会帮助你解决你的问题
select p.id,p.lname,p.fname from parents where (p.id not in (select pid from children))
union
select p.id,p.lname,p.fname from parents p,children c inner join on c.pid=p.id where c.active_flag=1 and c.expiration_date is null or c.expiration_date=''
union
select p.id,p.lname,p.fname from parents p inner join on c.pid=p.id where c.active_flag<>1;
答案 2 :(得分:0)
SELECT *
FROM parenttable pt
-- condition 1: There should be no parents without children at all
WHERE NOT EXISTS (
SELECT * FROM childtable c1
WHERE c1.parent_id = pt.id
)
-- condition 2: There should be no children with a flag but without a date
OR EXISTS (
SELECT * FROM childtable c2
WHERE c2.parent_id = pt.id
AND c2.active_flag = 1 AND c2.expire_date IS NULL
)
-- condition 3: There should at least be a child with the active_flag
OR NOT EXISTS (
SELECT * FROM childtable c3
WHERE c3.parent_id = pt.id
AND c2.active_flag = 1
)
;
-- Active flags for children c1 and c2
-- c1 c2 (X= child doesn't exists)
-----+-----+---+
-- X X rule1+rule3 # no children at all
-- 0 X rule3 # only one child
-- 1 X # idem
-- 0 0 rule 3 # two children
-- 0 1
-- 1 0
-- 1 1
--
-- , which means that rule3 implies rule1, and rule1 is redundant
-------------------------
SELECT *
FROM parenttable pt
-- condition 1+3: There should at least be a child with the active_flag
WHERE NOT EXISTS (
SELECT * FROM childtable c1
WHERE c1.parent_id = pt.id
AND c1.active_flag = 1
)
-- condition 2: There should be no children with a flag but without a date
OR EXISTS (
SELECT * FROM childtable c2
WHERE c2.parent_id = pt.id
AND c2.active_flag = 1 AND c2.expire_date IS NULL
)
;