#sql-server #tsql #column-alias
#sql-сервер #tsql #псевдоним столбца
Вопрос:
Задача: отобразить имена клиентов и их заказы, сделанные в Пуне и Калькутте в марте месяце
Клиенты:
CUST_ID CUST_NAME LOCATION
---------------------------------
1 A HYD
2 B PUNE
3 C DELHI
4 D KOLKATA
Заказы:
ORDER_ID CUST_ID AMOUNT DATE
----------------------------------
100 3 1000 2019-03-22
101 2 2000 2019-03-12
103 1 3000 2019-04-11
104 2 5000 2019-04-10
105 3 6000 2019-02-18
Запрос:
SELECT
c.cust_name, c.location,
CONVERT(VARCHAR(3), Date1, 100) AS Month
FROM
customers1 c
FULL OUTER JOIN
orders o ON o.cust_id = c.cust_id
WHERE
c.LOCATION = 'PUNE' OR c.LOCATION = 'KOLKATA'
GROUP BY
date1
HAVING
Month = 'Mar'
Я получаю эту ошибку:
Сообщение 207, уровень 16, состояние 1, строка 7
Недопустимое имя столбца «Месяц»
Ответ №1:
Невозможно ссылаться на псевдоним в вашем предложении HAVING. По соображениям производительности я предлагаю фильтровать по номеру месяца, а не по аббревиатуре месяца.
SELECT
c.cust_name
,c.location
,CONVERT(varchar(3), Date1, 100) as Month
FROM customers1 c
INNER JOIN orders o on o.cust_id=c.cust_id
WHERE
(c.LOCATION='PUNE' or c.LOCATION='KOLKATA')
WHERE
MONTH(Date1) = 3
Ответ №2:
То, что вы пытаетесь сделать, не работает в SQL Server, вы не можете использовать SELECT
псевдоним в WHERE
HAVING
предложении or (так, как вы это делаете).
Кроме того, внешнее соединение не требуется. Вы можете выразить то, что хотите, используя apply
:
select c.cust_name, c.location, v.month
from customers1 c join
orders o
on o.cust_id = c.cust_id cross apply
(values (CONVERT(varchar(3), Date1, 100))) v(Month)
where c.LOCATION in ('PUNE', 'KOLKATA') and
v.month = 'Mar';
Я понятия не имею, почему у вас есть group by date1
. date1
отсутствует в select
списке, и у вас нет функций агрегирования, поэтому агрегирование кажется ненужным.
Конечно, я бы упростил это до:
select c.cust_name, c.location,
left(datename(month, date1))
from customers1 c join
orders o
on o.cust_id = c.cust_idv(Month)
where c.LOCATION in ('PUNE', 'KOLKATA') and
month(date1) = 3;
Комментарии:
1. Кажется глупым преобразовывать каждую дату в сокращение месяца и фильтровать по этому. Вместо этого я бы отфильтровал номер месяца и сбросил APPLY() .
WHERE MONTH(Date1) = 3