Функция MySQL Lead возвращает NULL

У меня есть эта таблица MySQL:

идентификатор Имя 1 испанский 2 Французский 3 Немецкий

Я использую это утверждение:

SELECT id, Name, Lead(Name) OVER (ORDER BY id) AS 'next' from MyTable WHERE Name='French'

Ожидаемый результат таков:

идентификатор Имя следующий 2 Французский Немецкий

Результат таков:

идентификатор Имя следующий 2 Французский (НУЛЕВОЙ)

Это потому, что для id=2 нет «следующей» записи. Здесь только один. Возможно, вам действительно не нужен пункт OVER? Чего ты здесь ожидал?

Tim Roberts 07.07.2024 20:35

Тим, судя по тому, что я прочитал, «Более» является обязательной частью функции «Ведение». В порядке «id» следующая строка должна быть «Немецкий».

Cymro 07.07.2024 20:50

@Cymro LEAD рассчитывается после WHERE.

GSerg 07.07.2024 20:56

Используйте HAVING name = 'French', чтобы выполнить фильтр после получения набора результатов.

Barmar 07.07.2024 21:07

@Бармар Не поможет. Набор результатов формируется после применения HAVING (и его создание учитывает эффект предложения HAVING).

Akina 07.07.2024 21:22

Спасибо за комментарии. Вопрос в том, почему оно не работает. Насколько я вижу, я следую синтаксису. Пример с тем же синтаксисом находится здесь: docs.aws.amazon.com/redshift/latest/dg/r_WF_LEAD.html

Cymro 07.07.2024 21:28

@Cymro Вы говорите так, будто это должно работать, потому что вы следовали синтаксису, и что комментарии незначительно релевантны. На самом деле он работает именно так, как должен, и именно так, как описано в документации. То же самое верно и для всех других оконных функций. См. первые три абзаца docs.aws.amazon.com/redshift/latest/dg/c_Window_functions.ht‌​ml.

GSerg 07.07.2024 21:40

@GSerg, сообществу было бы полезно, если бы вы предоставили работающее решение. Спасибо. Вот почему мы здесь, верно? Помогать друг другу.

Cymro 07.07.2024 21:50
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
В последние годы архитектура микросервисов приобрела популярность как способ построения масштабируемых и гибких приложений. Laravel , популярный PHP...
Как построить CRUD-приложение в Laravel
Как построить CRUD-приложение в Laravel
Laravel - это популярный PHP-фреймворк, который позволяет быстро и легко создавать веб-приложения. Одной из наиболее распространенных задач в...
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
В предыдущем посте мы создали функциональность вставки и чтения для нашей динамической СУБД. В этом посте мы собираемся реализовать функции обновления...
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
Роли и разрешения пользователей без пакета Laravel 9
Роли и разрешения пользователей без пакета Laravel 9
Этот пост изначально был опубликован на techsolutionstuff.com .
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
В предыдущей статье мы завершили установку базы данных, для тех, кто не знает.
3
8
80
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Я не эксперт по SQL, но это работает:

With e AS (
    SELECT id, Name, Lead(Name) OVER (ORDER BY id) AS 'next' from MyTable 
) SELECT Id, Name, next FROM e WHERE Name='French'

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

/Редактировать: Этот код делает то же самое, и я полагаю, что он действительно будет более эффективен для больших таблиц, поскольку он не будет сначала вычислять все «следующие» поля для всей таблицы:

SELECT d.*, e.Next
    FROM MyTable d OUTER APPLY
    (SELECT TOP(1) Name AS Next
    FROM Mytable e 
    WHERE e.Id > d.Id
    ORDER BY Id
    ) AS e 
    WHERE d.Name = 'French'

Это сработало. Было бы здорово иметь решение с помощью одного выбора в соответствии с официальным синтаксисом, но, тем не менее, спасибо.

Cymro 07.07.2024 21:32

@Cymro «Официальный «Лид»» работает именно так, как должен. Функция была бы совершенно бесполезной, если бы она была вычислена раньше WHERE. То же самое и со всеми остальными оконными функциями. Неправильны ваши ожидания, а не результат функции или ее документации.

GSerg 07.07.2024 21:37

@Cymro, я думаю, вы не поняли точку зрения GSerg: ваш код сначала выбирает набор данных, где Language = 'French' (содержащий только 1 запись), а затем вычисляет 'next' (которого не существует для набора из 1 записи) ).

Lex W. 07.07.2024 21:57

@Лекс. вы даже не использовали «Lead» в своем решении, что подтверждает мое утверждение о том, что официальный синтаксис SQL для функции Lead — чушь. Я получил за это -3 балла? Я должен быть героем.

Cymro 08.07.2024 23:16

Официальный синтаксис LEAD жалок. Это должно быть так же, как в моем вопросе, как и для других функций SQL. Пример здесь: w3schools.com/sql/sql_sum.asp

Cymro 08.07.2024 23:25

@Cymro, SUM работает так же, как LEAD: функция применяется после предложения WHERE. Назвать это дерьмом - вопрос мнения..

Lex W. 08.07.2024 23:40

Лекс, я думаю, что SUM, AVG, MAX и т. д. используют логический синтаксис, отличный от синтаксиса LAG и LEAD. LAG и LEAD должны использовать один и тот же синтаксис, но это не так. Learnsql.com/blog/aggregate-functions-in-where-clause

Cymro 13.07.2024 22:51

Симро, ты, кажется, до сих пор этого не понимаешь. Все эти функции работают с набором, выбранным с помощью предложенияwhere. Все они. Но вы хотите, чтобы LAG и LEAD работали со всей таблицей, а затем выбирали ее подмножество.

Lex W. 14.07.2024 10:57

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