#sql #sql-server #sql-server-2012 #where-clause
#sql #sql-сервер #sql-server-2012 #предложение where
Вопрос:
В моем запросе есть вычисляемое поле, которое выглядит следующим образом:
(SELECT avg(RateAmount)/1.15
FROM ReservationStayDate f
where f.ReservationStayID = a.ReservationStayID) AS 'Rate Amount Excl.VAT'
В том же запросе мне нужно исключить все данные, где RatePlan начинается с ‘CO’ И приведенный выше результат = 0
Другими словами, мое предложение WHERE должно выглядеть примерно так:
AND NOT (d.rateplan like 'CO%' and (avg(RateAmount)/1.15)= 0)
Я получаю это сообщение об ошибке: недопустимое имя столбца ‘RateAmount’
Что здесь не так с синтаксисом?
ВОТ ПОЛНЫЙ ЗАПРОС:
SELECT a.ReservationStayID,
b.PropertyCode AS'Property',
b.ReservationStatus AS 'Status',
d.rsl_rateplan AS 'Rate Plan Code',
b.MarketSegmentCode AS 'Market Segment',
e.TravelAgencyTypeCode AS 'Source of Business',
a.ArrivalDate AS 'Date of Arrival',
a.DepartureDate AS 'Date of Departure',
c.AdultCount AS 'Adult',
c.ChildCount AS 'Child',
b.GuestCount AS 'Guest',
d.rsl_nationality AS 'Nationality',
c.PMSConfirmationNumber,
c.CurrencyCode As 'Currency',
e.Name AS 'Tour Operator',
e.CountryCode AS 'Market Code',
g.CountryGroup AS 'Market',
(SELECT avg(RateAmount)/1.15
FROM ReservationStayDate f
where f.ReservationStayID = a.ReservationStayID) AS 'Rate Amount Excl.VAT'
FROM GuestNameInfo a
JOIN GuestStaySummary b ON a.ReservationStayID = b.ReservationStayID
LEFT JOIN ReservationStay c ON c.ReservationStayID = b.ReservationStayID
LEFT JOIN P5RESERVATIONLIST d ON d.rsl_code = b.ReservationStayID
LEFT JOIN TravelAgency e ON e.TravelAgencyID = c.TAProfileID
LEFT JOIN Market g ON e.CountryCode = g.CountryCode
WHERE a.PrimaryGuest=' ' and d.rsl_primaryguest=' '
AND A.ARRIVALDATE <= '2013-09-30' AND A.DEPARTUREDATE > '2013-09-01'
ORDER BY a.ReservationStayID
Комментарии:
1. Вы не можете ссылаться на RateAmount, поскольку у вас, вероятно, нет таблицы (ReservationStayDate) в вашем основном запросе. Если вы добавите его в свой основной запрос, то это приведет к созданию нескольких строк для каждого ReservationStayID, так что это не поможет. Вероятно, вам нужно выполнить запрос в два прохода, один для получения данных, а другой для фильтрации результатов?
2. Если я включу столбец из ReservationStayDate в свой основной запрос, то это сработает?
3. Какую СУБД вы используете?
Ответ №1:
Без вашего полного запроса я не могу дать точное решение, но в SQL Server вы можете использовать APPLY, который будет работать как подвыборка, но это позволит вам повторно использовать созданный столбец, а также создать несколько столбцов. например
SELECT a.SomeField,
r.RateAmountExcVat
FROM SomeTable AS a
INNER JOIN SomeOtherTable AS d
ON d.SomeField = a.SomeField
--... Whatever else your query does...
OUTER APPLY
( SELECT RateAmountExcVat = AVG(RateAmount)/1.15
FROM ReservationStayDate AS f
WHERE f.ReservationStayID = a.ReservationStayID
) AS r
WHERE NOT (d.RatePlan LIKE 'CO%' AND r.RateAmountExcVat = 0);
Однако вам не обязательно использовать коррелированный подзапрос, обычный подзапрос будет работать точно так же. Таким образом, вместо выполнения агрегирования в вашем предложении select вы можете переместить агрегирование в подзапрос, что означает, что вы можете ссылаться на результат агрегирования во внешнем запросе.
SELECT a.SomeField,
r.RateAmountExcVat
FROM SomeTable AS a
INNER JOIN SomeOtherTable AS d
ON d.SomeField = a.SomeField
--... Whatever else your query does...
LEFT JOIN
( SELECT ReservationStayID,
RateAmountExcVat = AVG(RateAmount)/1.15
FROM ReservationStayDate AS f
GROUP BY ReservationStayID
) AS r
ON r.ReservationStayID = a.ReservationStayID
WHERE NOT (d.RatePlan LIKE 'CO%' AND r.RateAmountExcVat = 0);
Редактировать
Ваш полный запрос будет выглядеть примерно так.
SELECT a.ReservationStayID,
b.PropertyCode AS [Property],
b.ReservationStatus AS [Status],
d.rsl_rateplan AS [Rate Plan Code],
b.MarketSegmentCode AS [Market Segment],
e.TravelAgencyTypeCode AS [Source of Business],
a.ArrivalDate AS [Date of Arrival],
a.DepartureDate AS [Date of Departure],
c.AdultCount AS [Adult],
c.ChildCount AS [Child],
b.GuestCount AS [Guest],
d.rsl_nationality AS [Nationality],
c.PMSConfirmationNumber,
c.CurrencyCode As [Currency],
e.Name AS [Tour Operator],
e.CountryCode AS [Market Code],
g.CountryGroup AS [Market],
f.RateAmountExclVAT AS [Rate Amount Excl.VAT]
FROM GuestNameInfo a
JOIN GuestStaySummary b
ON a.ReservationStayID = b.ReservationStayID
LEFT JOIN ReservationStay c
ON c.ReservationStayID = b.ReservationStayID
LEFT JOIN P5RESERVATIONLIST d
ON d.rsl_code = b.ReservationStayID
LEFT JOIN TravelAgency e
ON e.TravelAgencyID = c.TAProfileID
LEFT JOIN Market g
ON e.CountryCode = g.CountryCode
LEFT JOIN
( SELECT ReservationStayID,
RateAmountExclVAT = AVG(RateAmount) / 1.15
FROM ReservationStayDate f
GROUP BY f.ReservationStayID
) AS f
ON f.ReservationStayID = a.ReservationStayID
WHERE a.PrimaryGuest=' '
AND d.rsl_primaryguest=' '
AND A.ARRIVALDATE <= '2013-09-30'
AND A.DEPARTUREDATE > '2013-09-01'
AND NOT (d.RatePlan like 'CO%' AND f.RateAmountExclVAT = 0)
ORDER BY a.ReservationStayID
Пара вещей, на которые стоит обратить внимание, это то, что я удалил ваш AS 'alias'
синтаксис, поскольку использование литералов в качестве псевдонимов столбцов устарело. [Дальнейшее чтение в Вредные привычки для удара : использование AS вместо = для псевдонимов столбцов . Я бы также рекомендовал использовать псевдонимы таблицы значений, а не просто a, b, c и т.д.
Комментарии:
1. Спасибо GarethD… Я отредактировал сообщение с моим полным запросом. Не могли бы вы, пожалуйста, помочь?
2. Большое спасибо, GarethD! Высоко ценится! Не должен ли r.RateAmountExclVAT быть f.RateAmountExclVAT?
Ответ №2:
Возьмите существующий запрос и удалите этот фрагмент предложения WHERE:
and (avg(RateAmount)/1.15)= 0
затем перепишите его следующим образом:
SELECT * FROM (
<your original query>
) a WHERE a.[Rate Amount Excl.VAT] != 0;
Это не самый красивый способ сделать это, но без полного запроса…
Ответ №3:
Попробуйте это
Select * from ReservationStayDate M
join
(SELECT f.ReservationStayID,avg(RateAmount)/1.15 R
FROM ReservationStayDate f
where f.ReservationStayID = a.ReservationStayID
and d.rateplan not like 'CO%'
group by f.ReservationStayID
) AS E
on E.ReservationStayID = M.ReservationStayID
where E.r = 0
или попробуйте это
(SELECT E.R
FROM ReservationStayDate f
join
(SELECT f.ReservationStayID,avg(RateAmount)/1.15 R
FROM ReservationStayDate f1
whered.rateplan not like 'CO%'
group by f.ReservationStayID
) AS E
on E.ReservationStayID = F.ReservationStayID
where E.r = 0
) AS 'Rate Amount Excl.VAT'
Комментарии:
1. Я не могу, потому что в своем запросе я извлекаю данные из других таблиц (в моем вопросе я показал только часть запроса), и мне нужна только средняя сумма ставки из таблицы ReservationStayDate.
2. В вашем подзапросе чего-то не хватает
GROUP BY f.ReservationStayID
. Этот ответ был бы существенно улучшен, если бы в нем было хотя бы одно предложение, объясняющее, какие изменения вы внесли и почему, вместо простого «Попробуйте это».3. Я получаю это сообщение об ошибке: «Не удалось привязать состоящий из нескольких частей идентификатор «f.ReservationStayID»».