Sql оператор with: Oracle PL/SQL оператор WITH — Oracle PL/SQL •MySQL •MariaDB •SQL Server •SQLite
Содержание
mariadb — SQL syntax error: оператор WITH
У меня есть запрос на mariaDB:
SELECT AVG(selectOnStop.time_avg) AS global_avg_time, AVG(selectFromStopTaskProcessor.time_avg) AS qmr_task_time, AVG(selectOnStop.time_avg) - AVG(selectFromStopTaskProcessor.time_avg) AS postprocessing FROM (SELECT global_task_id, SUM(time_from_start), SUM(time_from_start) / 1000000 AS time_avg FROM task AS t INNER JOIN recorderevent AS r ON (CONCAT(r.task_id, '0', SUBSTRING(r.`shard_alias` FROM 7)) = t.id) WHERE r.event_name = 'STOP' GROUP BY global_task_id ORDER BY SUM(time_from_start) DESC) AS selectOnStop JOIN (SELECT global_task_id, SUM(time_from_start) / 1000000 AS time_avg FROM task AS t INNER JOIN recorderevent AS r ON (CONCAT(r.task_id, '0', SUBSTRING(r.`shard_alias` FROM 7)) = t.id) WHERE r. event_name = 'QMR_STOP_TASK_PROCESSOR' GROUP BY global_task_id ORDER BY SUM(time_from_start) DESC) AS selectFromStopTaskProcessor;
Запрос работает. Я решил переписать его с использованием оператора WITH.
WITH selectOnStop (time_start, time_avg) AS (SELECT SUM(time_from_start) AS time_start, SUM(time_from_start) / 1000000 AS time_avg FROM task AS t INNER JOIN recorderevent AS r ON (CONCAT(r.task_id, '0', SUBSTRING(r.`shard_alias` FROM 7)) = t.id) WHERE r.event_name = 'STOP' GROUP BY global_task_id ORDER BY SUM(time_from_start) DESC) , selectFromStopTaskProcessor (time_average) AS (SELECT SUM(time_from_start) / 1000000 AS time_average FROM task AS t INNER JOIN recorderevent AS r ON (CONCAT(r. task_id, '0', SUBSTRING(r.`shard_alias` FROM 7)) = t.id) WHERE r.event_name = 'QMR_STOP_TASK_PROCESSOR' GROUP BY global_task_id ORDER BY SUM(time_from_start) DESC) SELECT AVG(selectOnStop.time_avg) AS global_avg_time, AVG(selectFromStopTaskProcessor.time_average) AS qmr_task_time, AVG(selectOnStop.time_avg) - AVG(selectFromStopTaskProcessor.time_average) AS postprocessing FROM selectOnStop JOIN selectFromStopTaskProcessor;
По сути, я просто перенёс селекты в отдельные запросы. Пишет следующее:
[42000][1064] (conn=3) You have an error in your SQL syntax; check the
manual that corresponds to your MariaDB server version for the right
syntax to use near ‘selectOnStop (time_start, time_avg) AS (SELECT
[42000][1064] You have an error in your SQL syntax; check the manual
that corresponds to your MariaDB server version for the right syntax
to use near ‘selectOnStop (time_start, time_avg) AS (SELECT ‘ at line
1 Query is: WITH selectOnStop (time_start, time_avg) AS (SELECT
SUM(time_from_start) AS time_sta . ..
Подскажите, что я делаю не так, и что надо поправить в запросе, чтобы он работал?
Оператор SQL WHERE — Примеры и синтаксис
ВВЕРХ
❮
❯
В большинстве случаев необходимо получать не все записи, а только те, которые соответствуют определенным критериям.
Поэтому для осуществления фильтрации выборки в SQL есть специальный оператор WHERE.
1. Простое фильтрование оператором WHERE.
Давайте из нашей таблицы, например, отберем записи, относящиеся только к определенному товару. Для этого мы укажем дополнительный параметр отбора, который будет фильтровать значение по колонке Product.
Пример запроса для отбора текстовых значений:
SELECT * FROM Sumproduct WHERE Product = 'Bikes'
Как видим, условие отбора взято в одинарные кавычки, что является обязательным при фильтровании текстовых значений. При фильтровании числовых значений кавычки не нужны.
Пример запроса для отбора числовых значений:
SELECT * FROM Sumproduct WHERE Amount > 40000 ORDER BY Amount
В этом примере мы отобрали записи, в которых выручка от реализации составила более 40 тыс. $ и, дополнительно, все записи посортировали по возрастанию по полю Amount.
В таблице ниже указан перечень условных операторов, поддерживаемых SQL:
Знак операции | Значение |
---|---|
= | Равно |
<> | Не равно |
< | Меньше |
<= | Меньше или равно |
> | Больше |
>= | Больше или равно |
BETWEEN | Между двумя значениями |
IS NULL | Отсутствует запись |
2. Фильтрация по диапазону значений (
BETWEEN).
Для отбора данных, которые лежат в определенном диапазоне, используется оператор BETWEEN. В следующем запросе будут отобраны все значения, лежащие в пределах от 1000 $ в 2000 $ включительно, в поле Amount.
SELECT * FROM Sumproduct WHERE Amount BETWEEN 1000 AND 2000
Очередность сортировки будет зависеть от порядка расположения полей в запросе. То есть, в нашем случае сначала данные будут посортированы по колонке Amount, а затем по City.
3. Выборка пустых записей (
IS NULL).
В SQL существует специальный оператор для выборки пустых записей (називаеьбся NULL). Пустой записью считается любая ячейка в таблице, в которую не введены какие-либо символы. Если в ячейку введен 0 или пробел, то считается, что поле заполнено.
SELECT * FROM Sumproduct WHERE Amount IS NULL
В примере выше, мы нарочно удалили два значения в поле Amount, чтобы продемонстрировать работу оператора NULL.
4. Расширенное фильтрации (
AND, OR).
Язык SQL не ограничивается фильтрацией по одному условию, для собственных целей вы можете использовать достаточно сложные конструкции для выборки данных одновременно по многим критериям. Для этого в SQL есть дополнительные операторы, которые расширяют возможности оператора WHERE. Такими операторами являются: AND, OR, IN, NOT. Приведем несколько примеров работы данных операторов.
SELECT * FROM Sumproduct WHERE Amount > 40000 AND City = 'Toronto'
SELECT * FROM Sumproduct WHERE Month = 'April' OR Month = 'March'
Давайте объединим операторы AND и OR. Для этого сделаем выборку велосипедов (Bikes) и коньков (Skates), которые были проданы в марте (March).
SELECT * FROM Sumproduct WHERE Product = 'Bikes' OR Product = 'Skates' AND Month = 'March'
Видим, что в нашу выборку попало за много значений (кроме марта (March), также январь (January), февраль (February) и апрель (April)). В чем же причина? А в том, что SQL имеет приоритеты выполнения команд. То есть оператор AND имеет более высокий приоритет, чем оператор OR, поэтому сначала были отобраны записи с коньками, которие проданные в марте, а потом все записи, касающиеся велосипедов.
Итак, чтобы получить правильную выборку, нам нужно изменить приоритеты выполнения команд. Для этого используем скобки, как в математике. Тогда, сначала будут обработаны операторы в скобках, а затем — все остальные.
SELECT * FROM Sumproduct WHERE (Product = 'Bikes' OR Product = 'Skates') AND Month = 'March'
5. Расширенная фильтрация (
оператор IN).
SELECT * FROM Sumproduct WHERE ID IN (4, 12, 58, 67)
Оператор IN выполняет ту же функцию, что и OR, однако имеет ряд преимуществ:
открывает большие возможности для создания сложных подзапросов.
6. Расширенная фильтрация (
оператор NOT).
SELECT * FROM Sumproduct WHERE NOT City IN ('Toronto', 'Montreal')
Ключевое слово NOT позволяет убрать ненужные значения из выборки. Также его особенностью является то, что оно проставляется перед названием столбца, участвующего в фильтровании, а не после.
Статьи по теме:
mysql — SQL-запрос с несколькими операторами where
Задавать вопрос
спросил
Изменено
1 год, 2 месяца назад
Просмотрено
501 тысяч раз
У меня довольно сложный для меня запрос mysql, на котором я полностью застрял и не могу найти ответ в Интернете.
Вот мой запрос:
ВЫБЕРИТЕ предметы.* ОТ предметы ВНУТРЕННЕЕ СОЕДИНЕНИЕ items_meta_data ГДЕ ( (meta_key = 'широта' AND meta_value >= '55') ИЛИ (meta_key = 'широта' AND meta_value <= '65') ) И ( (meta_key = 'long' AND meta_value >= '20') ИЛИ (meta_key = 'long' AND meta_value <= '30') ) ГРУППА ПО item_id
Конечно, я протестировал запрос только с одним оператором, и он отлично работает. Итак, если я прохожу только длинную или латную часть, я получаю результаты. Только когда я пытаюсь сшить их вместе, я получаю разные результаты.
Заранее спасибо за помощь!
Структура таблицы следующая:
Элементы таблицы: ИДЕНТИФИКАТОР имя элемента описание предмета Мета таблицы: мета_ид item_id мета_ключ мета_значение
Решение
Кому интересно Мне наконец удалось решить эту проблему. Всем спасибо за помощь и внутренности.
ВЫБЕРИТЕ Элементы SQL_CALC_FOUND_ROWS.* ОТ предметы ВНУТРЕННЕЕ СОЕДИНЕНИЕ items_meta ON (items. ID = items_meta.post_id) ВНУТРЕННЕЕ СОЕДИНЕНИЕ items_meta AS m1 ON (items.ID = m1.post_id) ГДЕ 1=1 И items.post_type = 'сообщение' И (items.post_status = 'опубликовать') И ((items_meta.meta_key = 'lat' AND CAST(items_meta.meta_value AS SIGNED) МЕЖДУ '55' И '65') И (m1.meta_key = 'long' AND CAST (m1.meta_value AS SIGNED) МЕЖДУ '20' И '30')) ГРУППА ПО элементы.ID СОРТИРОВАТЬ ПО элементы.дата DESC
4
Необходимо учитывать, что GROUP BY
происходит после оценки условий пункта WHERE
. И предложение WHERE
всегда учитывает только одну строку, а это означает, что в вашем запросе условия meta_key
всегда будут препятствовать выбору любых записей, поскольку один столбец не может иметь несколько значений для одной строки .
А как насчет избыточных проверок meta_value? Если значение может быть как меньше, так и больше заданного значения, то его фактическое значение не имеет значения — проверку можно не проводить.
Согласно одному из ваших комментариев, вы хотите проверить места, находящиеся на расстоянии меньше определенного расстояния от заданного места. Чтобы получить правильные расстояния, вам действительно нужно использовать какую-то правильную функцию расстояния (подробности см., Например, в этом вопросе). Но этот SQL должен дать вам представление о том, как начать:
SELECT items.* FROM items i, meta_data m1, meta_data m2 ГДЕ i.item_id = m1.item_id и i.item_id = m2.item_id И m1.meta_key = 'lat' И m1.meta_value >= 55 И m1.meta_value <= 65 И m2.meta_key = 'lng' И m2.meta_value >= 20 И m2.meta_value <= 30
3
Это..
( (meta_key = 'lat' AND meta_value >= '60.23457047672217') ИЛИ (meta_key = 'lat' AND meta_value <= '60.23457047672217') )
совпадает с
( (meta_key = 'широта') )
Сложив все это вместе (то же самое относится к фильтру long
), вы получите это невозможное предложение WHERE, которое не даст строк, потому что meta_key
не может быть 2 значениями в одной строке
ГДЕ (meta_key = 'широта' И meta_key = 'длина')
Вам необходимо проверить своих операторов, чтобы убедиться, что вы используете правильную логику
3
Что такое meta_key
? Удалите все условные выражения meta_value
, уменьшите, и вы получите это:
SELECT * ОТ мета_данные ГДЕ ( (meta_key = 'широта') ) И ( (meta_key = 'длинный') ) ГРУППА ПО item_id
С meta_key
никогда не может одновременно равняться двум разным значениям, результаты возвращаться не будут.
Судя по комментариям к этому вопросу и ответам на данный момент, похоже, что вы ищете нечто большее, например:
ВЫБЕРИТЕ * ОТ мета_данные ГДЕ ( (meta_key = 'широта') И ( (мета_значение >= '60.23457047672217') ИЛИ (мета_значение <= '60.23457047672217') ) ) ИЛИ ( (meta_key = 'длинный') И ( (мета_значение >= '24,879140853881836') ИЛИ (мета_значение <= '24,879140853881836') ) ) ГРУППА ПО item_id
Обратите внимание на ИЛИ
между условными операторами верхнего уровня. Это потому, что вам нужны записи lat
или long
, поскольку ни одна запись никогда не будет lat
и long
.
Я все еще не уверен, чего вы пытаетесь достичь с помощью внутренних условий. Любое ненулевое значение будет соответствовать этим числам. Так что, может быть, вы можете уточнить, что вы пытаетесь там сделать. Я также не уверен в цели GROUP BY
, но это может быть полностью вне контекста этого вопроса.
6
Можно посмотреть структуру вашей таблицы? Если я это понимаю, то предположение, сделанное запросом, состоит в том, что запись может быть только meta_key - 'lat'
или meta_key = 'long'
, а не обе, потому что каждая строка имеет только один столбец meta_key
и может только содержат 1 соответствующее значение, а не 2. Это объясняет, почему вы не получаете результатов при соединении с И
; это невозможно.
1
Зарегистрируйтесь или войдите в систему
Зарегистрируйтесь с помощью Google
Зарегистрироваться через Facebook
Зарегистрируйтесь, используя электронную почту и пароль
Опубликовать как гость
Электронная почта
Обязательно, но не отображается
Опубликовать как гость
Электронная почта
Требуется, но не отображается
Нажимая «Опубликовать свой ответ», вы соглашаетесь с нашими условиями обслуживания и подтверждаете, что прочитали и поняли нашу политику конфиденциальности и кодекс поведения.
Оператор SQL с использованием предложения Where с несколькими значениями
спросил
Изменено
3 года, 7 месяцев назад
Просмотрено
787 тысяч раз
У меня есть таблица с несколькими строками со следующими полями:
PersonName SongName Статус
Я хочу использовать имена, выбранные из списка с множественным выбором, значения которых я могу получить, а затем выполнить предложение where, чтобы оно отображало названия песен, которые все выбранные люди могут играть, поэтому статус завершен.
Например:
PersonName SongName Статус Холли Хайленд завершена Холли Мех завершена Райан Хайленд завершен
Если я выберу Холли и Райана из списка и нажму кнопку, запрос должен просто показать Highland, поскольку это то, что они оба знают.
2
Попробуйте это:
выберите songName из t где имя человека в ("Райан", "Холли") группа по названию песни имея количество (отличное имя человека) = 2
Количество в наличии должно соответствовать количеству людей. Если вам также нужно, чтобы Статус был Завершено
, используйте это предложение , где
вместо предыдущего:
, где имя человека в ('Райан', 'Холли') и статус = 'Завершено'
6
ВЫБЕРИТЕ PersonName, songName, статус ИЗ таблицы ГДЕ имя В («Холли», «Райан»)
Если вы используете параметризованную хранимую процедуру:
- Передайте строку, разделенную запятыми
- Используйте специальную функцию для разделения строки, разделенной запятыми, на переменную табличного значения
- Используйте
INNER JOIN ON t.PersonName = newTable.PersonName
, используя табличную переменную, которая содержит переданные имена
2
Выберите t1.