2016-08-22 2 views
-1

У меня есть следующий запрос: результатSQL, отфильтровывать же идентификаторы, если нуль существует

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 с тем же идентификатором, если один из них 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 с по меньшей мере одним PropOptionIdnot null

Мой результат запроса должен выглядеть следующим образом:

MilgaId PropertyId PropOptionId 
937  90   2291 
937  132   2434 
+2

Вы уверены, что вы хотите, LEFT JOIN? – jarlh

+0

Я думаю, что большинство кодеров поставили условия поиска в предложение 'WHERE' для ясности, например. 'sd.UserId = 'A270D9AC-0D73-4E01-8CBC-D3C5812CCA97'' и' m.IsEnable = 1'. – onedaywhen

+0

'Каждый milgaId должен иметь все PropertyId с хотя бы одним PropOptionId не null' ... тогда почему' '38' отфильтровывается? Вам нужно очистить свою логику здесь. –

ответ

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 
+0

удаляет нулевые, но не все остальные с тем же MilgaId – Eyal

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 
+0

Я все еще получаю MilgaId = 938.те, у кого есть null, где удалены, но не другие с тем же milgaId – Eyal

+0

@Eyal Я обновил свой ответ, повторите попытку. –

+0

Выглядит хорошо. делая еще несколько тестов. Спасибо. – Eyal

1

Yo можно добавить еще одно условие (проверить производительность)

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 
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. Так что дайте мне знать, если что-то не получится :)

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 
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 
Смежные вопросы