Объединить два запроса SELECT с разными предложениями WHERE

9

У меня есть одна таблица услуг. Мне нужно объединить два запроса SELECT. У обоих разные пункты where. Например

SELECT 
  U_REGN as 'Region', 
  COUNT(callID) as 'OpenServices',
  SUM(CASE WHEN descrption LIKE '%DFC%' THEN 1 ELSE 0 END) 'DFC'
FROM OSCL
WHERE     
  ([status] = - 3) 
GROUP BY 
  U_REGN
ORDER BY 
  'OpenServices' desc

Это дает мне результат

Region    | OpenServices | DFC
Karaci    | 14           | 4
Lahore    | 13           | 3
Islamabad | 10           | 4

У меня есть другой запрос

SELECT 
  U_REGN as 'Region', 
  COUNT(callID) as 'ClosedYesterday'
FROM OSCL
WHERE 
  DATEDIFF(day, closeDate, GETDATE()) = 1
GROUP BY 
  U_REGN
ORDER BY 
  'ClosedYesterday' desc

Это дает мне результат

Region    | ClosedServices
Karachi   | 8
Lahore    | 7
Islamabad | 4

Мне нужно объединить оба результата и показать ClosedServices рядом со столбцом DFC.

TheSarfaraz
источник
Есть несоответствие - ваш второй запрос создает столбец с именем ClosedYesterday, но данные примера говорят о ClosedServices.
Майкл Грин,
Что означает «слияние»?
philipxy

Ответы:

15

Рассматривайте результаты двух ваших текущих запросов как таблицы и объединяйте их:

select
    FirstSet.Region,
    FirstSet.OpenServices,
    FirstSet.DFC,
    SecondSet.ClosedYesterday
from 
(
    SELECT U_REGN as 'Region', COUNT(callID) as 'OpenServices',
    SUM(CASE WHEN descrption LIKE '%DFC%' THEN 1 ELSE 0 END) 'DFC'
    FROM OSCL 
    WHERE ([status] = - 3) 
    GROUP BY U_REGN 
    --ORDER BY 'OpenServices' desc
) as FirstSet
inner join
(
    SELECT U_REGN as 'Region', 
    COUNT(callID) as 'ClosedYesterday'
    FROM OSCL
    WHERE DATEDIFF(day, closeDate, GETDATE()) = 1
    GROUP BY U_REGN
    --ORDER BY 'ClosedYesterday' desc
) as SecondSet
on FirstSet.Region = SecondSet.Region
order by FirstSet.Region

Не самый красивый кусочек SQL, который я когда-либо писал, но, надеюсь, вы увидите, как он работает, и поймете, как его поддерживать.

Я подозреваю, что более эффективный запрос будет синглом SELECTиз OSCL, сгруппированным по U_REGN, с каждым из трех ваших счетчиков в качестве отдельных SUM(CASE ...)операторов, похожих на то, что вы делаете в настоящее время для DFC. В большинстве случаев это будет сканирование одной таблицы, в зависимости от ваших индексов и схемы.

Майкл Грин
источник
2
Что происходит, когда в одном подзапросе есть результаты, которых нет в другом? Я подозреваю, что вы на самом деле хотите полное внешнее соединение здесь.
Саймон Ригартс
@ Симон - справедливо, но это не был заданный сценарий ОП.
Майкл Грин
Спасибо, это то, что я хотел, спасибо! А также Спасибо @SimonRigharts. Внутреннее объединение не показывало мне все результаты, которые я намеревался, поэтому я использовал полное внешнее объединение, работает отлично :)
TheSarfaraz
6

Основываясь на предложении Майкла:

SELECT
    U_REGN AS 'Region',
    SUM(CASE WHEN [status] = -3 THEN 1 ELSE 0 END) AS 'OpenServices',
    SUM(CASE WHEN [status] = -3 AND [description] LIKE '%DFC%' THEN 1 ELSE 0 END) AS 'DFC',
    SUM(CASE WHEN DATEDIFF(day, closeDate, GETDATE()) = 1 THEN 1 ELSE 0 END) AS 'ClosedYesterday'
FROM
    OSCL
GROUP BY 
    U_REGN
ORDER BY
    'OpenServices' desc
Саймон Ригартс
источник
1
Спасибо, Саймон, но я использовал запрос @Michael Green с полным внешним объединением, потому что этот запрос дает мне даже те регионы, в которых нет открытых или закрытых сервисов!
TheSarfaraz