SQL,如果存在null,则过滤掉相同的Id

时间:2016-08-22 07:20:00

标签: sql sql-server

我有以下查询:

SELECT        
    m.MilgaId, 
    opt.PropertyId, 
    sd.PropOptionId
FROM            
    Milga AS m INNER JOIN
    PropertyOptionInMilga AS poInMil ON m.MilgaId = poInMil.MilgaId INNER JOIN
    PropertyOption AS opt on poInMil.PropertyOptionId = opt.PropertyOptionId LEFT JOIN
    StudentData AS sd on sd.UserId = 'A270D9AC-0D73-4E01-8CBC-D3C5812CCA97' 
AND opt.PropertyId = sd.PropertyId
    GROUP BY 
        m.MilgaId, 
        opt.PropertyId, 
        sd.PropOptionId, 
        m.IsEnable
    HAVING  
        (m.IsEnable = 1)
    ORDER BY 
        m.MilgaId

查询结果:

MilgaId PropertyId  PropOptionId
937       90            2291
937       132           2434
938       25            38
938       91            NULL        <-----
938       132           2434

如果其中一个MilgaId,我会过滤掉具有相同ID的所有null - 应该过滤掉milgaId=938的所有行。

我的查询结果应如下所示:

MilgaId PropertyId  PropOptionId
937       90            2291
937       132           2434

* ***更正:

查询结果:

MilgaId PropertyId  PropOptionId
937       90            2291
937       132           null       <-----  132 with null
937       132           2434       <-----  132 has one without null so it's in result
938       25            38
938       91            NULL        <----- 
938       132           2434
939       201           2600
939       202           null

**每个milgaId必须包含至少一个PropertyId PropOptionId的所有not null

我的查询结果应如下所示:

MilgaId PropertyId  PropOptionId
937       90            2291
937       132           2434

6 个答案:

答案 0 :(得分:1)

WITH CTE (MilgaId, PropertyId, PropOptionId, IsEnable)
AS
(
SELECT m.MilgaId, 
       opt.PropertyId, 
       sd.PropOptionId,
       m.IsEnable
FROM            
    Milga AS m
INNER JOIN
PropertyOptionInMilga AS poInMil
    ON m.MilgaId = poInMil.MilgaId
INNER JOIN
PropertyOption AS opt
    ON poInMil.PropertyOptionId = opt.PropertyOptionId
LEFT JOIN
StudentData AS sd
    ON sd.UserId = 'A270D9AC-0D73-4E01-8CBC-D3C5812CCA97' AND
       opt.PropertyId = sd.PropertyId
)

SELECT t1.MilgaId, 
       t1.PropertyId, 
       t1.PropOptionId
FROM CTE t1
INNER JOIN
(
    SELECT t.MilgaId
    FROM CTE t
    GROUP BY t.MilgaId
    HAVING SUM(CASE WHEN t.PropOptionId IS NOT NULL THEN 1 ELSE 0 END) > 0
) t2
    ON t1.MilgaId = t2.MilgaId
GROUP BY 
    t1.MilgaId, 
    t1.PropertyId, 
    t1.PropOptionId, 
    t1.IsEnable
HAVING  
    (t1.IsEnable = 1) AND
ORDER BY 
    t1.MilgaId

答案 1 :(得分:1)

哟可以添加一个条件(检查性能)

  AND m.MilgaId NOT IN(SELECT DISTINCT  poInMil.MilgaId 
PropertyOptionInMilga AS poInMil  INNER JOIN
PropertyOption AS opt ON poInMil.PropertyOptionId = opt.PropertyOptionId 
LEFT JOIN  StudentData AS sd ON sd.UserId = 'A270D9AC-0D73-4E01-8CBC-D3C5812CCA97' AND opt.PropertyId = sd.PropertyId 
WHERE sd.PropertyId IS NULL)
像这样:

SELECT        
    m.MilgaId, 
    opt.PropertyId, 
    sd.PropOptionId
FROM            
    Milga AS m INNER JOIN
    PropertyOptionInMilga AS poInMil ON m.MilgaId = poInMil.MilgaId INNER JOIN
    PropertyOption AS opt ON poInMil.PropertyOptionId = opt.PropertyOptionId LEFT JOIN
    StudentData AS sd ON sd.UserId = 'A270D9AC-0D73-4E01-8CBC-D3C5812CCA97' 
AND opt.PropertyId = sd.PropertyId

AND m.MilgaId NOT IN(SELECT DISTINCT  poInMil.MilgaId 
PropertyOptionInMilga AS poInMil  INNER JOIN
PropertyOption AS opt ON poInMil.PropertyOptionId = opt.PropertyOptionId 
LEFT JOIN  StudentData AS sd ON sd.UserId = 'A270D9AC-0D73-4E01-8CBC-D3C5812CCA97' AND opt.PropertyId = sd.PropertyId 
WHERE sd.PropertyId IS NULL)
    GROUP BY 
        m.MilgaId, 
        opt.PropertyId, 
        sd.PropOptionId, 
        m.IsEnable
    HAVING  
        (m.IsEnable = 1)
    ORDER BY 
        m.MilgaId

答案 2 :(得分:0)

试试这个:

SELECT        
    m.MilgaId, 
    opt.PropertyId, 
    sd.PropOptionId
FROM            
    Milga AS m INNER JOIN
    PropertyOptionInMilga AS poInMil ON m.MilgaId = poInMil.MilgaId INNER JOIN
    PropertyOption AS opt on poInMil.PropertyOptionId = opt.PropertyOptionId LEFT JOIN
    StudentData AS sd on sd.UserId = 'A270D9AC-0D73-4E01-8CBC-D3C5812CCA97' AND opt.PropertyId = sd.PropertyId
WHERE sd.PropOptionId IS NOT NULL
GROUP BY 
    m.MilgaId, 
    opt.PropertyId, 
    sd.PropOptionId, 
    m.IsEnable

HAVING  
    (m.IsEnable = 1)

ORDER BY 
    m.MilgaId

答案 3 :(得分:0)

以下是我对该问题的看法

SELECT        
    m.MilgaId, 
    opt.PropertyId, 
    sd.PropOptionId
FROM Milga AS m
INNER JOIN PropertyOptionInMilga AS poInMil on (m.MilgaId = poInMil.MilgaId)
INNER JOIN PropertyOption AS opt on (poInMil.PropertyOptionId = opt.PropertyOptionId)
LEFT JOIN StudentData AS sd on (sd.UserId = 'A270D9AC-0D73-4E01-8CBC-D3C5812CCA97' AND opt.PropertyId = sd.PropertyId)
left join (
select MilgaId from milga m
INNER JOIN PropertyOptionInMilga AS poInMil on (m.MilgaId = poInMil.MilgaId)
INNER JOIN PropertyOption AS opt on (poInMil.PropertyOptionId = opt.PropertyOptionId)
LEFT JOIN StudentData AS sd on (sd.UserId = 'A270D9AC-0D73-4E01-8CBC-D3C5812CCA97' AND opt.PropertyId = sd.PropertyId and sd.PropOptionId is null)) m2
on (m.MilgaId = m2.MilgaId)
where m2.MilgaId is null
    GROUP BY 
        m.MilgaId, 
        opt.PropertyId, 
        sd.PropOptionId, 
        m.IsEnable
    HAVING  
        (m.IsEnable = 1)
    ORDER BY 
        m.MilgaId

遗憾的是,我无法在SQL Server上测试它。 如果有任何事情失败,请告诉我:))

答案 4 :(得分:0)

我不知道sd.PropOptionId可以是什么值,但我想这个值必须大于0所以。我尝试这个查询(但我没有测试)

SELECT *
FROM (
    SELECT        
        m.MilgaId, 
        opt.PropertyId, 
        sd.PropOptionId,
        MIN(ISNULL(sd.PropOptionId,-99)) OVER (PARTITION BY m.MilgaId) AS [minVal]
    FROM            
        Milga AS m INNER JOIN
        PropertyOptionInMilga AS poInMil ON m.MilgaId = poInMil.MilgaId INNER JOIN
        PropertyOption AS opt on poInMil.PropertyOptionId = opt.PropertyOptionId LEFT JOIN
        StudentData AS sd on sd.UserId = 'A270D9AC-0D73-4E01-8CBC-D3C5812CCA97' 
    AND opt.PropertyId = sd.PropertyId
    WHERE m.IsEnable = 1
    ORDER BY 
        m.MilgaId
) q
WHERE q.minVal > 0

答案 5 :(得分:0)

我采用了不同的方法:

Select milgaId, MilgaName from 
    (
        SELECT   m.milgaId,m.MilgaName, count(distinct(opt.PropertyId)) as CntPropertyIdInMilga
        FROM            Milga AS m INNER JOIN
                                 PropertyOptionInMilga AS poInMil ON m.MilgaId = poInMil.MilgaId INNER JOIN
                                 PropertyOption AS opt ON poInMil.PropertyOptionId = opt.PropertyOptionId
        WHERE        (m.IsEnable = 1) AND 
                    (m.IsSpecial = 0)
        group by m.Milgaid,m.MilgaName
    )  
As tbl
    Where 
    (
        SELECT         count(distinct(sd.PropertyId))  as PropertyInStudentData
        FROM            Milga AS m INNER JOIN
                                 PropertyOptionInMilga AS poInMil ON m.MilgaId = poInMil.MilgaId INNER JOIN
                                 PropertyOption AS opt ON poInMil.PropertyOptionId = opt.PropertyOptionId INNER JOIN
                                 StudentData AS sd ON opt.PropertyOptionId = sd.PropOptionId AND sd.UserId = 'A8F60C49-960F-4A6D-A759-925077607C5A'
        WHERE        
                    (m.IsEnable = 1) AND 
                    (m.IsSpecial = 0)  AND
                    (m.MilgaId = tbl.MilgaId)
        group by m.Milgaid
    )  = CntPropertyIdInMilga