ПРИСОЕДИНЯЙТЕСЬ к двум результатам SELECT

174

Можно ли объединить результаты 2 SQL- SELECTоператоров в одном операторе? У меня есть база данных задач, где каждая запись - это отдельная задача со сроками исполнения (и a PALT, который составляет всего несколько INTдней от начала до крайнего срока. AgeЭто также INTколичество дней.)

Я хочу иметь таблицу, в которой есть каждый человек в таблице, количество задач, которые у них есть, и количество LATEзадач, которые у них есть (если есть).

Я могу легко получить эти данные в отдельных таблицах, например:

SELECT ks, COUNT(*) AS '# Tasks' FROM Table GROUP BY ks

возвращая данные как:

ks        # Tasks
person1   7
person2   3

и тогда у меня есть:

SELECT ks, COUNT(*) AS '# Late' FROM Table WHERE Age > Palt GROUP BY ks

который возвращает:

ks        # Late
person1   1
person2   1

И я хочу присоединиться к результатам этих двух selectзаявлений (по KS)

Я пытаюсь избежать использования временной таблицы, но если это единственный практический способ сделать это, я хотел бы узнать больше об использовании временных таблиц таким способом.

Я также пытался count()создать какие-то строки, которые удовлетворяли бы условию, но я также не мог понять, как это сделать. Если это возможно, это тоже сработает.

Приложение: К сожалению, я хочу , чтобы мои результаты , чтобы иметь столбцы KS, TasksиLate

KS        # Tasks   # Late
person1   7         1
person2   3         1
person3   2         0  (or null)

Кроме того, я хочу, чтобы человек появился, даже если у него нет поздних заданий.

SUM(CASE WHEN Age > Palt THEN 1 ELSE 0 END) Late
работает хорошо, спасибо за этот ответ!

Также работают два оператора select, с помощью LEFT JOINкоторых также можно присоединиться к ним, и теперь я понимаю, как объединить несколько selects таким способом.

sylverfyre
источник
Вы не привели пример ожидаемого результата. Таким образом, некоторые ответы касаются результатов. Некоторые присоединяются. Какой вы хотите?
Фил
Извините, я хочу, чтобы в моих результатах были столбцы для KS, Tasks и Late KS # Задачи # Late person1 7 1 person2 3 1 person3 2 0 (или null) Кроме того, я хочу, чтобы этот человек появлялся, даже если у него нет поздних задач , В настоящее время это достигается с помощью метода двух операторов select с LEFT JOIN (в отличие от предложенного INNER JOIN, который работает, но не показывает людей, у которых нет поздних задач, потому что их нет во втором SELECT. Также достигается это с поздним колонку быть SUM (CASE WHEN Возраст> PALT THEN 1 ELSE 0 END) Late
sylverfyre

Ответы:

264
SELECT t1.ks, t1.[# Tasks], COALESCE(t2.[# Late], 0) AS [# Late]
FROM 
    (SELECT ks, COUNT(*) AS '# Tasks' FROM Table GROUP BY ks) t1
LEFT JOIN
    (SELECT ks, COUNT(*) AS '# Late' FROM Table WHERE Age > Palt GROUP BY ks) t2
ON (t1.ks = t2.ks);
Фил
источник
1
Это хорошо работает, хотя я не указал, что я хочу левое соединение, чтобы записи отображались, даже если у них 0 поздних задач.
sylverfyre
Принял этот ответ, потому что он отвечает на вопрос, который я задал лучше всего, и отформатирован таким образом, чтобы быть отличным справочником по ПРИСОЕДИНЕНИЮ операторов SELECT :)
sylverfyre
Отличный ответ, но кто-то может сказать, является ли этот тип «решения» дорогим или зависит только от того, для чего вы его используете?
Petrosmm
71

Попробуйте что-то вроде этого:

SELECT 
* 
FROM
(SELECT ks, COUNT(*) AS '# Tasks' FROM Table GROUP BY ks) t1 
INNER JOIN
(SELECT ks, COUNT(*) AS '# Late' FROM Table WHERE Age > Palt GROUP BY ks) t2
ON t1.ks = t2.ks
Mithrandir
источник
4
Я не мог получить принятый ответ на работу, но это отлично сработало для моих нужд. Спасибо.
benvenker
Работал как шарм. Насколько я понимаю, это должен быть принятый ответ. Спасибо.
nocdib
Работал на меня! Спасибо! Я также попытался использовать несколько запросов (несколько соединений), и это также отлично работает. Если кому-то интересно, вы можете просто добавить больше JOINs после последнего «ON» в примере и продолжать использовать последовательность: ON .... X JOIN (QUERY N -1) ON Y = ZX JOIN (QUERY N) ON Y = Z
cesarmart
44

Используйте UNION:

SELECT ks, COUNT(*) AS '# Tasks' FROM Table GROUP BY ks
UNION
SELECT ks, COUNT(*) AS '# Late' FROM Table WHERE Age > Palt GROUP BY ks

Или, UNION ALLесли вы хотите дубликаты:

SELECT ks, COUNT(*) AS '# Tasks' FROM Table GROUP BY ks
UNION ALL
SELECT ks, COUNT(*) AS '# Late' FROM Table WHERE Age > Palt GROUP BY ks
аР.
источник
3
Союз или Союз Все будут иметь только 2 столбца в результате. Где, как он хочет 3 из них
SurajS
14

Если Age и Palt являются столбцами в одной и той же таблице, вы можете посчитать (*) все задачи и суммировать только поздние, например:

select ks,
       count(*) tasks,
       sum(case when Age > Palt then 1 end) late
  from Table
 group by ks
Никола Марковинович
источник
1
Это именно то, что я хотел, но не знал, как искать это. Я не думал об использовании суммы (случай) - спасибо.
sylverfyre
13

Вы можете использовать UNION ALLключевое слово для этого.

Вот документ MSDN, чтобы сделать это в T-SQL http://msdn.microsoft.com/en-us/library/ms180026.aspx

UNION ALL - объединяет набор результатов

UNION - делает что-то вроде Set Union и не выводит повторяющиеся значения

Для разницы с примером: http://sql-plsql.blogspot.in/2010/05/difference-between-union-union-all.html

Baz1nga
источник