Можно ли использовать UNION для объединения 3-х запросов результатов, сохраняя при этом разные столбцы? - PullRequest
1 голос
/ 31 января 2012

Итак, вот мой вопрос (кстати, я использую Oracle SQL)

У меня есть 3 запроса результатов из моей базы данных (один - общее количество отелей, один - количество строящихся отелей и один - количество завершенных отелей).

Как объединить все три запроса, чтобы я получил 1 строку и 3 отдельных столбца? Я пытался использовать UNION, но все, что меня выводит, это 1 столбец, но 3 строки.

Мой код выглядит так:

 (SELECT COUNT(Hotel.hotelName) AS TotalHotels FROM Hotel)
 UNION
 (SELECT COUNT(Hotel.hotelName) AS NumConstructing FROM Hotel
 WHERE NOT EXISTS
 (SELECT Room.* FROM Room WHERE Room.hotelNo = Hotel.hotelNo))
 UNION
 (SELECT COUNT(Hotel.hotelName) AS NumCompleted FROM Hotel
 WHERE EXISTS
 (SELECT Room.* FROM Room WHERE Room.hotelNo = Hotel.hotelNo));

И полученный результат выглядит так:

TOTALHOTELS
-----------
  2
  8
 10

Мне нужно, чтобы была только одна строка и 3 столбца.

Любая помощь?

Ответы [ 4 ]

3 голосов
/ 31 января 2012

Общий ответ, который также работает, когда ваши SELECT результаты имеют более одного столбца, таков:

SELECT TotalHotels, NumConstructing, NumCompleted
FROM
    (SELECT COUNT(Hotel.hotelName) AS TotalHotels FROM Hotel)
    AS TotalHotels
CROSS JOIN 
    (SELECT COUNT(Hotel.hotelName) AS NumConstructing FROM Hotel
     WHERE NOT EXISTS
     (SELECT Room.* FROM Room WHERE Room.hotelNo = Hotel.hotelNo))
    AS NumConstructing
CROSS JOIN
    (SELECT COUNT(Hotel.hotelName) AS NumCompleted FROM Hotel
     WHERE EXISTS
     (SELECT Room.* FROM Room WHERE Room.hotelNo = Hotel.hotelNo))
    AS NumCompleted;

, хотя в этом случае вам не требуется объединение / перекрестное объединение:

SELECT
    COUNT(1) AS TotalHotels,
    COUNT(CASE WHEN NOT EXISTS
     (SELECT 1 FROM Room WHERE Room.hotelNo = Hotel.hotelNo) THEN 1 END) AS NumConstructing,
    COUNT(CASE WHEN EXISTS
     (SELECT 1 FROM Room WHERE Room.hotelNo = Hotel.hotelNo) THEN 1 END) AS NumCompleted
FROM
    Hotel;
1 голос
/ 31 января 2012

В самом базовом преобразовании:

select 
(SELECT COUNT(Hotel.hotelName) FROM Hotel) AS TotalHotels 
, (SELECT COUNT(Hotel.hotelName) FROM Hotel
   WHERE NOT EXISTS
   (SELECT Room.* FROM Room WHERE Room.hotelNo = Hotel.hotelNo)) AS NumConstructing 
, (SELECT COUNT(Hotel.hotelName) FROM Hotel
   WHERE EXISTS
   (SELECT Room.* FROM Room WHERE Room.hotelNo = Hotel.hotelNo)) AS NumCompleted
from dual;
0 голосов
/ 30 декабря 2014

Это делается с помощью подзапросов и двойной таблицы:

SELECT (SELECT COUNT(Hotel.hotelName) FROM Hotel) AS TotalHotels,
       (SELECT COUNT(Hotel.hotelName) 
          FROM Hotel
         WHERE NOT EXISTS (SELECT Room.* 
                             FROM Room 
                            WHERE Room.hotelNo = Hotel.hotelNo)) AS NumConstructing,
       (SELECT COUNT(Hotel.hotelName) AS NumCompleted  
          FROM Hotel
         WHERE EXISTS (SELECT Room.* 
                         FROM Room 
                        WHERE Room.hotelNo = Hotel.hotelNo))
  FROM dual;

Однако для производительности я бы использовал что-то вроде этого (извините за возможные опечатки):

SELECT Count(DISTINCT h.hotelNo) TotalHotels,
       Sum(Decode(r.hotelNo,
                  NULL, 1,
                  0) NumConstructing,
       Sum(Decode(r.hotelNo,
                  NULL, 0,
                  1) NumCompleted
  FROM Hotel h,
       Room  r
 WHERE h.hotelNo = r.hotelNo (+)  
0 голосов
/ 31 января 2012
SELECT 
 (SELECT COUNT(Hotel.hotelName) FROM Hotel) AS TotalHotels,
 (SELECT COUNT(Hotel.hotelName) FROM Hotel WHERE NOT EXISTS (SELECT Room.* FROM Room WHERE Room.hotelNo = Hotel.hotelNo)) AS NumConstructing,
 (SELECT COUNT(Hotel.hotelName) FROM Hotel WHERE EXISTS (SELECT Room.* FROM Room WHERE Room.hotelNo = Hotel.hotelNo)) AS NumCompleted
...