Присоединитесь к SQL операторам select с помощью Union - PullRequest
0 голосов
/ 10 июля 2020

Я пытаюсь объединить три запроса select с помощью Union All, но отображается ошибка. Когда я присоединяюсь к первым двум операторам select, он работает нормально. Когда я добавил третий оператор, я не могу его выполнить.

SQL Запрос

WITH CTE_BOOKINGS (TotalRecurrance,TotalBookingsWithoutRecurrance,TotalBookingsWithRecurrance,RoomID) AS
(
SELECT 0,count(BK.pkBookingID) as TotalBookingsWithoutRecurrance,0, RM.roomID as RoomID
FROM dbo.tblBooking BK WITH (NOLOCK)
INNER JOIN dbo.tblBookingItem BI WITH (NOLOCK) ON BK.pkBookingID=BI.fkBookingID
INNER JOIN dbo.tblBookingDateTime BDT WITH (NOLOCK) ON BK.pkBookingID=BDT.fkBookingID
INNER JOIN Enterprise.tblRooms RM WITH (NOLOCK) ON BI.fkItemID=RM.roomID AND RM.fkResourceId=1
WHERE
BK.deleteBooking=0
AND BDT.UTC_bookingEnd > GETUTCDATE()
AND BI.primaryRoom=1
AND BI.Active=1
AND NOT EXISTS (select * from tblBookingRecurrance where fkBookingID=BK.pkBookingID AND ACTIVE=1)
AND RM.roomID=16867
group by RM.roomID

UNION ALL
 
SELECT count(distinct BR.fkRecurranceID) as TotalRecurrance,0,0, RM.roomID as RoomID
FROM dbo.tblBooking BK WITH (NOLOCK)
INNER JOIN dbo.tblBookingItem BI WITH (NOLOCK) ON BK.pkBookingID=BI.fkBookingID
INNER JOIN dbo.tblBookingDateTime BDT WITH (NOLOCK) ON BK.pkBookingID=BDT.fkBookingID
INNER JOIN Enterprise.tblRooms RM WITH (NOLOCK) ON BI.fkItemID=RM.roomID AND RM.fkResourceId=1
INNER JOIN tblBookingRecurrance BR WITH (NOLOCK) ON BK.pkBookingID=BR.fkBookingID
WHERE
BK.deleteBooking=0
AND BDT.UTC_bookingEnd > GETUTCDATE()
AND BI.primaryRoom=1
AND BI.Active=1
AND RM.roomID=16867
AND BR.active=1
group by RM.roomID

UNION ALL

SELECT 0,0,count(BK.pkBookingID) as TotalBookingsWithRecurrance, RM.roomID as RoomID
FROM dbo.tblBooking BK WITH (NOLOCK)
INNER JOIN dbo.tblBookingItem BI WITH (NOLOCK) ON BK.pkBookingID=BI.fkBookingID
INNER JOIN dbo.tblBookingDateTime BDT WITH (NOLOCK) ON BK.pkBookingID=BDT.fkBookingID
INNER JOIN Enterprise.tblRooms RM WITH (NOLOCK) ON BI.fkItemID=RM.roomID AND RM.fkResourceId=1
WHERE
BK.deleteBooking=0
AND BDT.UTC_bookingEnd > GETUTCDATE()
AND BI.primaryRoom=1
AND BI.Active=1
AND RM.roomID=16867
group by RM.roomID
)

SELECT  SUM(TotalRecurrance + TotalBookingsWithoutRecurrance) as TotalBookings, TotalBookingsWithRecurrance, RoomID FROM CTE_BOOKINGS Group BY RoomID order by 1 desc

Когда я запускаю запрос, отображается следующая ошибка:

Ошибка

Column 'CTE_BOOKINGS.TotalBookingsWithRecurrance' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.

Ответы [ 2 ]

1 голос
/ 10 июля 2020

При использовании UNION имена столбцов из первого SELECT возвращаются для всего набора результатов. Таким образом, даже если вы укажете «TotalBookingsWithoutRecurrance», «TotalRecurrance» и «TotalBookingsWithRecurrance», заголовок столбца вашего набора результатов (учитывая ваш текущий пример) будет «TotalRecurrance».

Я считаю, что ваша проблема заключается в вашем последнем SELECT :

SELECT  SUM(TotalRecurrance + TotalBookingsWithoutRecurrance) as TotalBookings, TotalBookingsWithRecurrance, RoomID FROM CTE_BOOKINGS Group BY RoomID order by 1 desc

TotalBookingsWithRecurrance не группируется, и вы не выполняете какое-то агрегирование - отсюда и ошибка.

Чтобы оставить как есть ' d необходимо сделать:

SELECT SUM(TotalRecurrance + TotalBookingsWithoutRecurrance) as TotalBookings, TotalBookingsWithRecurrance, RoomID 
FROM CTE_BOOKINGS 
GROUP BY RoomID, TotalBookingsWithRecurrance
ORDER BY 1 DESC

Однако это добавит дополнительный уровень группировки, который, как я подозреваю, вам не нужен.

Кроме того, кажется, что ваши столбцы не выровнены между вашими Объединенные операторы, что является обязательным - по крайней мере, это лучшая практика (в любом случае для меня).

Я не могу это проверить, но попробуйте сделать что-то вроде следующего:

WITH CTE_BOOKINGS ( RoomID, RecurranceType, Recurrance, UnknownCol1, UnknownCol2  ) 
AS (    
    SELECT 
        RM.roomID AS RoomID,
        'TotalBookingsWithoutRecurrance' AS RecurranceType,
        COUNT ( BK.pkBookingID ) AS Recurrance,
        0 AS UnknownCol1,
        0 AS UnknownCol2
    FROM dbo.tblBooking BK WITH (NOLOCK)
    INNER JOIN dbo.tblBookingItem BI WITH (NOLOCK) ON BK.pkBookingID=BI.fkBookingID
    INNER JOIN dbo.tblBookingDateTime BDT WITH (NOLOCK) ON BK.pkBookingID=BDT.fkBookingID
    INNER JOIN Enterprise.tblRooms RM WITH (NOLOCK) ON BI.fkItemID=RM.roomID AND RM.fkResourceId=1
    WHERE BK.deleteBooking=0
        AND BDT.UTC_bookingEnd > GETUTCDATE()
        AND BI.primaryRoom=1
        AND BI.Active=1
        AND NOT EXISTS (select * from tblBookingRecurrance where fkBookingID=BK.pkBookingID AND ACTIVE=1)
        AND RM.roomID=16867
    GROUP BY RM.roomID
    UNION ALL
    SELECT 
        RM.roomID AS RoomID,
        'TotalRecurrance' AS RecurranceType,
        COUNT ( DISTINCT BR.fkRecurranceID ) AS Recurrance,
        0 AS UnknownCol1,
        0 AS UnknownCol2 
    FROM dbo.tblBooking BK WITH (NOLOCK)
    INNER JOIN dbo.tblBookingItem BI WITH (NOLOCK) ON BK.pkBookingID=BI.fkBookingID
    INNER JOIN dbo.tblBookingDateTime BDT WITH (NOLOCK) ON BK.pkBookingID=BDT.fkBookingID
    INNER JOIN Enterprise.tblRooms RM WITH (NOLOCK) ON BI.fkItemID=RM.roomID AND RM.fkResourceId=1
    INNER JOIN tblBookingRecurrance BR WITH (NOLOCK) ON BK.pkBookingID=BR.fkBookingID
    WHERE BK.deleteBooking=0
        AND BDT.UTC_bookingEnd > GETUTCDATE()
        AND BI.primaryRoom=1
        AND BI.Active=1
        AND RM.roomID=16867
        AND BR.active=1
    GROUP BY RM.roomID
    UNION ALL
    SELECT 
        RM.roomID AS RoomID,
        'TotalBookingsWithRecurrance' AS RecurranceType,
        COUNT ( BK.pkBookingID ) AS Recurrance, 
        0 AS UnknownCol1,
        0 AS UnknownCol2
    FROM dbo.tblBooking BK WITH (NOLOCK)
    INNER JOIN dbo.tblBookingItem BI WITH (NOLOCK) ON BK.pkBookingID=BI.fkBookingID
    INNER JOIN dbo.tblBookingDateTime BDT WITH (NOLOCK) ON BK.pkBookingID=BDT.fkBookingID
    INNER JOIN Enterprise.tblRooms RM WITH (NOLOCK) ON BI.fkItemID=RM.roomID AND RM.fkResourceId=1
    WHERE BK.deleteBooking=0
        AND BDT.UTC_bookingEnd > GETUTCDATE()
        AND BI.primaryRoom=1
        AND BI.Active=1
        AND RM.roomID=18841
    GROUP BY RM.roomID
)
SELECT
    SUM ( 
        CASE WHEN RecurranceType IN ( 'TotalRecurrance', 'TotalBookingsWithoutRecurrance' ) THEN Recurrance ELSE 0 END 
    ) AS TotalBookings, 
    SUM ( 
        CASE WHEN RecurranceType = 'TotalBookingsWithRecurrance' THEN Recurrance ELSE 0 END 
    ) AS TotalBookingsWithRecurrance, 
    RoomID 
FROM CTE_BOOKINGS
GROUP BY RoomID
ORDER BY 1 DESC;
0 голосов
/ 10 июля 2020

Полученная ошибка не имеет ничего общего с UNION. Ошибка третьего запроса. Вам нужно исправить это, прежде чем вы сможете присоединить его к другому 2.

Если вы группируете по одному полю, это поле будет единственным, доступным для выбора без агрегатной функции. Вот сообщение , объясняющее это более подробно.

Глядя на ваш запрос, вы фильтруете по указанному c roomId, не уверен, какова ваша точная цель, но в этом случае , вам не нужна группа по roomId.

...