Начальный раздел SQL: избегание повторного выражения
Я полностью новичок в SQL, но, скажем, в Проводнике данных StackExchange я просто хочу перечислить 15 лучших пользователей по репутации, и я написал что-то вроде этого:
SELECT TOP 15
DisplayName, Id, Reputation, Reputation/1000 As RepInK
FROM
Users
WHERE
RepInK > 10
ORDER BY Reputation DESC
В настоящее время это приводит к Error: Invalid column name 'RepInK'
, что, я думаю, имеет смысл, поскольку RepInK
не является столбцом в Users
. Я легко могу это исправить, сказав WHERE Reputation/1000 > 10
, по сути повторяя формулу.
Итак, вопросы:
- Могу ли я на самом деле использовать
RepInK
"столбец" в WHERE
? - Возможно, мне нужно создать виртуальную таблицу/представление с этим столбцом, а затем выполнить запрос
SELECT/WHERE
?
- Могу ли я назвать выражение, например,
Reputation/1000
, чтобы мне пришлось повторять имена только в нескольких местах вместо формулы? - Как вы это называете? Макрос подстановки? Функция? Хранимая процедура?
- Есть ли таблица SQL-запросов, глоссарий терминов, спецификация языка, что-нибудь, что я могу использовать, чтобы быстро понять синтаксис и семантику языка?
- Я так понимаю, что есть разные "ароматы"?
Ответы
Ответ 1
Могу ли я использовать столбец RepInK в предложении WHERE?
Нет, но вы можете быть уверены, что ваша база данных будет оценивать (Reputation / 1000)
один раз, даже если вы используете ее как в полях SELECT
, так и в предложении WHERE
.
Возможно, мне нужно создать виртуальную таблицу/представление с этим столбцом, а затем выполнить запрос SELECT/WHERE?
Да, представление является одним из вариантов упрощения сложных запросов.
Могу ли я назвать выражение, например. Репутация /1000, поэтому мне нужно только повторять имена в нескольких местах вместо формулы?
Вы можете создать определенную пользователем функцию, которую вы можете вызвать как convertToK
, которая получит значение rep в качестве аргумента и возвращает этот аргумент, деленный на 1000. Однако это часто бывает непрактичным для тривиального случая, подобного одному в вашем примере.
Есть ли SQL-лист SQL, глоссарий терминов, спецификация языка, все, что я могу использовать, чтобы быстро подобрать синтаксис и семантику языка?
Я предлагаю практику. Вы можете начать использовать тег mysql для, где каждый день задают много начинающих вопросов. Загрузите MySQL, и когда вы подумаете, что есть вопрос, который вам подходит, попытайтесь найти решение. Я думаю, что это поможет вам получить скорость, а также понимание особенностей языков. Не нужно сначала публиковать ответ, потому что здесь есть довольно быстрые пушки, но с некоторой практикой я уверен, что вы сможете принести домой несколько моментов:)
Я понимаю, что существуют разные "ароматы"?
Ароматизаторы на самом деле являются расширениями ANSI SQL. Производители баз данных обычно добавляют язык SQL с расширениями, такими как Transact-SQL и PL/SQL.
Ответ 2
Вы можете просто переписать предложение WHERE
where reputation > 10000
Это не всегда будет удобно. Как альтернативно, вы можете использовать встроенный просмотр:
SELECT
a.DisplayName, a.Id, a.Reputation, a.RepInK
FROM
(
SELECT TOP 15
DisplayName, Id, Reputation, Reputation/1000 As RepInK
FROM
Users
ORDER BY Reputation DESC
) a
WHERE
a.RepInK > 10
Ответ 3
Что касается именованных выражений, в то время как существует несколько возможных альтернатив, оптимизатор запросов будет лучше всего использовать формулу Reputation / 1000
long-hand. Если вам действительно нужно запустить целую группу запросов с использованием одного и того же оцененного значения, лучше всего создать представление с заданным полем, но вы не захотите делать это для одноразового запроса.
В качестве альтернативы (и в тех случаях, когда производительность не является большой проблемой), вы можете попробовать что-то вроде:
SELECT TOP 15
DisplayName, Id, Reputation, RepInk
FROM (
SELECT DisplayName, Id, Reputation, Reputation / 1000 as RepInk
FROM Users
) AS table
WHERE table.RepInk > 10
ORDER BY Reputation DESC
хотя я не верю, что поддерживается всеми диалектами SQL, и, опять же, оптимизатор, скорее всего, сделает гораздо худшую работу, подобную этой вещи (так как она будет запускать SELECT в отношении полной таблицы Users, а затем фильтровать ее результат). Тем не менее, для некоторых ситуаций такой запрос подходит (есть имя для этого... Я рисую пробел в данный момент).
Лично, когда я начал с SQL, я нашел W3 school, чтобы быть моей постоянной точкой остановки. Это соответствует моему стилю того, что я могу заглянуть, чтобы найти быстрый ответ и двигаться дальше. В конце концов, однако, чтобы действительно воспользоваться базой данных, необходимо углубиться в документацию поставщиков.
Хотя SQL является "стандартизированным", к сожалению (хотя, в некоторой степени, к счастью), каждый поставщик базы данных реализует свою собственную версию с собственными расширениями, что может привести к тому, что наиболее подходящий синтаксис является наиболее подходящим (для обсуждения несовместимости различных баз данных по одному вопросу см. в документации SQLite для обработки NULL. В частности, стандартные функции, например, для обработки DATE и TIME, отличаются друг от друга, и есть другие, более резкие отличия (в частности, в подзапросах без поддержки или правильном обращении с JOIN). Если вы интересуетесь некоторыми деталями, this документ предоставляет как стандартные формы, так и отклонения для нескольких основных баз данных.
Ответ 4
Вы CAN ссылаетесь на RepInK в предложении Order By
, но в предложении Where
вы должны повторить выражение. Но, как говорили другие, он будет выполнен только один раз.
Ответ 5
Уже есть хорошие ответы на техническую проблему, поэтому я рассмотрю только некоторые из ваших вопросов.
Если вы просто работаете с DataExplorer, вам нужно будет ознакомиться с синтаксисом SQL Server, так как это работает. Лучшее место, чтобы найти это, конечно, ссылка MSDN.
Да, существуют различные варианты синтаксиса SQL. Например, предложение TOP
в запросе, которое вы указали, является специфичным для SQL Server; в MySQL вы должны использовать предложение LIMIT
вместо этого (и эти ключевые слова не обязательно отображаются в одном и том же месте в запросе!).