1

在出现新情况之前,我一直在查询大部分问题,这让我感到困惑。给定以下简化的表模式:

父表:

ID  
FName  
LName 

子表:

[Index]  
ParentID  
Active_Flag  
ExpirationDate 

我想要做的是获取父行:

  1. 没有孩子。
  2. 有些孩子的 Active_Flag 为 1,但其到期日期为空白或 NULL。
  3. 确实有孩子,但没有一个将 Active_Flag 设置为 1。

以下查询提出了我的前两个条件:

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。任何帮助表示赞赏。提前致谢。

4

3 回答 3

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 确实是整数,则可以简化必须“求和(ActiveFlag)”。如果不是,那么它应该是“='1'”而不是“=1'。

于 2012-09-14T20:50:34.050 回答
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;
于 2012-09-14T21:04:32.797 回答
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
        )
        ;
于 2012-09-15T13:51:44.370 回答