Премахване на дублиращи се редове от SQL UNION Query

Имам следната заявка за обединение, от която се опитвам да премахна дублиращи се редове:

SELECT DISTINCT c.Cat_Name, s.SubCat_DisplayName, st.State, COUNT(a.SubCategory_ID) as SubCount
FROM CT_SubCategory s
INNER JOIN CT_Category c ON s.Cat_ID=c.Cat_ID
INNER JOIN CT_AdvertiserSubcategory a ON s.Subcat_ID = a.SubCategory_ID
INNER JOIN CT_AdvertiserCity ac ON ac.UserID = a.UserID
INNER JOIN CT_City ci ON ci.City_ID = ac.City_ID
INNER JOIN CT_State st ON ci.State_ID = st.State_ID
WHERE ci.CityName LIKE 'Grand-Rapids' AND st.Abbr = 'MI'
GROUP BY c.Cat_Name, s.SubCat_Name, s.SubCat_DisplayName, st.State
UNION
SELECT c.Cat_Name, s.SubCat_Name, s.SubCat_DisplayName, null, null
FROM CT_SubCategory s
INNER JOIN CT_Category C ON s.Cat_ID = c.Cat_ID
ORDER BY SubCat_DisplayName

Текущи резултати:

Auto, Auto Repair, null, null
Auto, Auto Repair, Michigan, 3
Entertainment, Events, null, null
Gifts, Flowers, null, null

Желани резултати:

Auto, Auto Repair, Michigan, 3
Entertainment, Events, null, null
Gifts, Flowers, null, null

Бих искал да премахна дублиращия се ред Auto Repair с нули от моя набор от резултати.

Възможно ли е това да се направи със заявка за обединение?


person David    schedule 24.01.2015    source източник
comment
ще трябва да дедупирате след оператора за обединение, но ако искате да премахнете редове с NULL стойности, правите това във вашата клауза WHERE   -  person Beth    schedule 24.01.2015
comment
трябва да покажете очаквания резултат в сравнение с текущия резултат, който получавате, който сте показали по-горе, вашият очакван резултат не е ясен за нас   -  person null    schedule 24.01.2015


Отговори (2)


както разбрах въпроса, изобщо не се нуждаете от UNION, трябва да използвате LEFT OUTER JOIN;

SELECT DISTINCT c.Cat_Name, s.SubCat_DisplayName, st.State, COUNT(a.SubCategory_ID) as SubCount
FROM CT_SubCategory s
INNER JOIN CT_Category c ON s.Cat_ID=c.Cat_ID
LEFT OUTER JOIN CT_AdvertiserSubcategory a ON s.Subcat_ID = a.SubCategory_ID
LEFT OUTER JOIN CT_AdvertiserCity ac ON ac.UserID = a.UserID
LEFT OUTER JOIN CT_City ci ON ci.City_ID = ac.City_ID
LEFT OUTER JOIN CT_State st ON ci.State_ID = st.State_ID
WHERE ISNULL(ci.CityName,'Grand-Rapids') LIKE 'Grand-Rapids' AND ISNULL(st.Abbr,'MI') = 'MI'
GROUP BY c.Cat_Name, s.SubCat_Name, s.SubCat_DisplayName, st.State

и резултатът трябва да е така:

Auto, Auto Repair, Michigan, 3
Entertainment, Events, null, null
Gifts, Flowers, null, null
person null    schedule 24.01.2015
comment
Вашата клауза where отменя left join. - person Gordon Linoff; 24.01.2015
comment
@GordonLinoff, отговорът е редактиран, също така можете да поставите клаузата where извън заявката (make as subquery) - person null; 24.01.2015
comment
AND st.Abbr = 'MI' все още отменя външното съединение на st. Трябва да е в състояние на присъединяване. - person Sebas; 24.01.2015
comment
Отговорът на @Sebas е редактиран, но мисля, че най-добрият начин в този случай е да изведете клаузата where извън заявката като select * from (select tbla.a as a, tblb.b as b from tbla left outer join tblb on tbla.id=tblb.id) where b='some value' - person null; 24.01.2015
comment
също така мисля, че the idea of using left join е важен, а не детайлите на заявката, които собственикът на въпроса може да манипулира - person null; 24.01.2015

Отговорът на Farhang е ок. Но правилният начин да напишете заявката е да поставите условието where в клаузата on:

SELECT DISTINCT c.Cat_Name, s.SubCat_DisplayName, st.State,
       COUNT(a.SubCategory_ID) as SubCount
FROM CT_SubCategory s INNER JOIN
     CT_Category c
     ON s.Cat_ID = c.Cat_ID LEFT OUTER JOIN
     CT_AdvertiserSubcategory a
     ON s.Subcat_ID = a.SubCategory_ID LEFT OUTER JOIN
     CT_AdvertiserCity ac
     ON ac.UserID = a.UserID LEFT OUTER JOIN
     CT_City ci
     ON ci.City_ID = ac.City_ID AND
        ci.CityName = 'Grand-Rapids' LEFT OUTER JOIN
     CT_State st
     ON ci.State_ID = st.State_ID AND
        st.Abbr = 'MI'
GROUP BY c.Cat_Name, s.SubCat_Name, s.SubCat_DisplayName, st.State;

ISNULL() (или както предпочитам COALESCE()) връща неочаквани резултати, ако CityName или Abbr някога е NULL в данните. За филтриране в дясната таблица в left join, трябва да поставите условията в клаузата on.

person Gordon Linoff    schedule 24.01.2015
comment
Страхотен отговор. Използвам вграден контрол на Kentico CMS, така че трябва да имам условието where като пълен израз, за ​​да работи с Kentico - person David; 25.01.2015