Неожиданный синтаксис псевдонима SQL Server 'AS'

Сегодня я столкнулся со следующим T-SQL:

select c from (select 1 union all select 1) as  d(c)

что дает следующий результат:

c
-----------
1
1

Меня смутила часть Округ Колумбия)

Пытаясь понять, что происходит, я изменил T-SQL на:

select c, b from (select 1, 2 union all select 3, 4) m(c, b)

что дает следующий результат:

c           b
----------- -----------
1           2
3           4

Стало ясно, что г и м — это ссылки на таблицы, а буквы в скобках с и б — на столбцы. Мне не удалось найти соответствующую документацию в msdn, но любопытно, если

  1. Вы знаете о таком синтаксисе?
  2. Какой был бы полезный сценарий использования?

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

Dale K 17.03.2022 10:05

1. Да. 2. Точно так же, как вы его использовали; при использовании производной таблицы, в которой не определены псевдонимы столбцов. 3 Это В самом деле отвечает на ваш вопрос?

Larnu 17.03.2022 10:05

Руководство по вопросам @daleK, это не правило, а просто руководство, любопытно, как бы вы отобразили набор результатов, включая имена столбцов? Результат в текст? гораздо уродливее, чем изображение, которое я разместил

krul 17.03.2022 13:51

@Damien_The_Unbeliever определяет жесткий взгляд ... Предположение, что все узнают производную таблицу в опубликованном sql летучей мыши, я полагаю, что стоит за вашим комментарием, который может объяснить мои трудности с поиском соответствующей документации.

krul 17.03.2022 13:55

Ответ @Larnu IamDave отлично отвечает на мой вопрос (возможно, плохо поставленный).

krul 17.03.2022 14:20

Изображения еще более уродливы для тех, кто использует программы чтения с экрана, @krul, а изображения текста уродливы для копирования и вставки в готовый текст.

Larnu 17.03.2022 14:33

@larnu красота в глазах смотрящего ... тут согласен не согласиться thumbs.dreamstime.com/z/…

krul 17.03.2022 14:49

К сожалению для вас, @krul, вы не согласны с часто задаваемыми вопросами, которым мы просим пользователей следовать. Невыполнение этого требования может легко привести к отрицательным или, возможно, закрытым голосованиям. Если вы хотите опубликовать изображения текста, не «расстраивайтесь», если вы их получите; это был ваш выбор — использовать контент, который этого требует. Полезность > красота (особенно когда красота в глазах смотрящего, а бесполезность — нет).

Larnu 17.03.2022 14:52

@Larnu, можете ли вы указать мне точное правило, которое я нарушил? И кстати, как вы диагностировали мое эмоциональное состояние "расстроен"

krul 17.03.2022 14:54

Если вы внимательно прочитаете мой вопрос, вы не найдете изображений кода/ошибок, так какое же правило я нарушил?

krul 17.03.2022 15:00

@krul текст, который я разместил, является дословным из мастера вопросов, когда вы задаете вопрос, чтобы повторить «пожалуйста, не публикуйте изображения кода, данных, сообщений об ошибках ...» обратите внимание, что он говорит код, дата, ошибки. И вам нужно только посмотреть на несколько других вопросов в этом теге, чтобы найти хорошо отформатированные текстовые данные с именами столбцов.

Dale K 17.03.2022 20:02
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
0
12
89
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

select c from (select 1 union all select 1) as d(c)

такой же как

select c from (select 1 as c union all select 1) as d

В первом запросе вы не назвали столбцы в своем подзапросе, но назвали их вне подзапроса,

Во втором запросе вы называете столбцы внутри подзапроса.

Если вы попробуете это так (без указания столбцов в подзапросе)

select c from (select 1 union all select 1) as d

Вы получите следующую ошибку

No column name was specified for column 1 of 'd'

Это тоже есть в Документация

Что касается использования, то кому-то нравится писать первым способом, кому-то вторым, кому как больше нравится. Все то же самое

Ответ принят как подходящий

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

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

Примером адресных значений может быть гораздо более сложная версия следующего, в которой вычисленные значения в производной таблице v могут использоваться много раз с помощью более разумных имен, а не повторных вычислений, за которыми будет трудно следовать:

select p.ProductName
      ,p.PackPricePlusVAT - v.PackCost as GrossRevenue
      ,etc
from dbo.Products as p
    cross apply(values(p.UnitsPerPack * p.UnitCost
                      ,p.UnitPrice * p.UnitsPerPack * 1.2
                      ,etc
                      )
               ) as v(PackCost
                     ,PackPricePlusVAT
                     ,etc
                     )

и примером возможности дублирования строк может быть создание отчета об исключениях для использования при проверке данных, который будет выводить одну строку для каждого условия DataError, которому удовлетворяет строка dbo.Product:

select p.ProductName
      ,e.DataError
from dbo.Products as p
    cross apply(values('Missing Units Per Pack'
                      ,case when p.SoldInPacks = 1 and isnull(p.UnitsPerPack,0) < 1 then 1 end
                      )
                     ,('Unusual Price'
                      ,case when p.Price > (p.UnitsPerPack * p.UnitCost) * 2 then 1 end
                      )
                     ,(etc)
               ) as e(DataError
                     ,ErrorFlag
                     )
where e.ErrorFlag = 1

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

Наблюдение: использование конструктора таблиц values не дает вам возможности называть столбцы, что делает необходимым использовать имена столбцов после псевдонима таблицы:

select * from
(values
     (1,2) -- can't give a column name here
    ,(3,4)
) as tableName(column1,column2) -- gotta do it here

Другие вопросы по теме