Ошибка оператора Group BY для получения уникальных записей

Я новичок в SQL Server, раньше работал с MYSQL и пытался получить записи из таблицы с помощью Group By.

Структура таблицы представлена ​​ниже:

SELECT S1.ID,S1.Template_ID,S1.Assigned_By,S1.Assignees,S1.Active FROM "Schedule" AS S1;

Выход:

ID Template_ID  Assigned_By Assignees Active
2   25          1           3         1
3   25          5           6         1
6   26          5           6         1

Мне нужно получить значения всех столбцов, используя оператор Group By ниже

SELECT Template_ID FROM "Schedule" WHERE "Assignees" IN(6, 3) GROUP BY "Template_ID";

Выход:

Template_ID

25
26

Я попробовал следующий код для получения таблицы с помощью Group By, но он извлекает все строки.

SELECT S1.ID,S1.Template_ID,S1.Assigned_By,S1.Assignees,S1.Active FROM "Schedule" AS S1 INNER JOIN(SELECT Template_ID FROM "Schedule" WHERE "Assignees" IN(6, 3) GROUP BY "Template_ID") AS S2 ON S2.Template_ID=S1.Template_ID

Мой вывод должен быть таким,

   ID Template_ID  Assigned_By Assignees Active
    2   25          1           3         1
    6   26          5           6         1

Мне было интересно, могу ли я получить идентификатор столбца? Я использую идентификатор для редактирования записей в Интернете.

Запрос, который вы запрашиваете, — недействителен даже в MySQL. Однако вы работали с синтаксисом не поддерживается, который выдает ошибку в последних версиях и возвращает случайные результаты в более ранних версиях — в таблице или запросе нет неявного порядка, если только он не указан ORDER BY, поэтому сервер вернет первое значение, возвращенное выполнением запроса.

Panagiotis Kanavos 30.05.2019 08:51

У MySql не было проблем с GroupBy. Я пытаюсь понять, как SQL извлекает идентификаторы с помощью Group By

Zendie 30.05.2019 08:55

да, это так, и я только что разместил ссылку на Документы MySQL, которая объясняет это. Вы использовали неподдерживаемый хак. Раньше у вас был неверный запрос, который приводил к MySQL 5.7. это все еще плохой запрос в SQL Server или любой другой базе данных. В более старых версиях MySQL вы получали случайные значения вместо первой строки.

Panagiotis Kanavos 30.05.2019 08:55
group by для агрегации, я думаю, вы хотите использовать оконная функция, чтобы получить номер строки и взять первую строку для каждого template_id?
Dale K 30.05.2019 08:56

@ Дейл Баррелл, да. У меня была ошибка агрегации, а затем я попробовал этот запрос

Zendie 30.05.2019 08:58

@Зенди, что ты хочешь сделать? Почему вы хотите использовать GROUP BY, если хотите вернуть все столбцы? Даже в MySQL поддерживается способ использования ROW_NUMBER() или одной из других функций ранжирования, представленных в MySQL 8.0.

Panagiotis Kanavos 30.05.2019 08:59

@Zendie, вы должны знать, что, поскольку это не поддерживается, MySQL не проверяет его поведение. Запросы с неагрегированными столбцами в MySQL 5.7 выполняются намного хуже, чем в более ранних версиях.

Panagiotis Kanavos 30.05.2019 09:01

@Зенди из 5.6 документыThe server is free to choose any value from each group, so unless they are the same, the values chosen are nondeterministic.

Panagiotis Kanavos 30.05.2019 09:03

Я хочу вернуть только одну строку из таблицы, в которой пользователь принадлежит к группе (то есть назначенным)

Zendie 30.05.2019 09:03

@Zendie только одна строка по каким критериям? Случайный? Самый маленький идентификатор?

Panagiotis Kanavos 30.05.2019 09:09

@PanagiotisKanavos ВЫБЕРИТЕ ИДЕНТИФИКАТОР_шаблона ИЗ «Расписания», ГДЕ «Уполномоченные» В (6, 3) СГРУППИРОВАТЬ ПО «ИДЕНТИФИКАТОРу_шаблона»; Это именно то, что я хочу сделать, но для этого результата мне нужны и другие значения столбца. Наименьший идентификатор будет отображаться

Zendie 30.05.2019 09:10

Если Template_ID = 25, это соответствует 2 строкам, но вы хотите отобразить только одну строку, но хотите отобразить все значения. Вы понимаете, почему мы в замешательстве? Если вы хотите отобразить все значения без агрегирования, вам нужно выбрать строку.

Dale K 30.05.2019 09:16

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

Dale K 30.05.2019 09:17

@DaleBurrell Спасибо, я посмотрю оконную функцию. Мне нужно сгруппировать записи по TemplateID. И необходимо отображать значения самого низкого идентификатора, назначенного и активного значения.

Zendie 30.05.2019 09:20

Если вы хотите сгруппировать и показать самые низкие значения, просто используйте функцию min

Dale K 30.05.2019 09:23
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
0
15
50
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

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

Запрос не работает должным образом и в MySQL, разве что случайно.

Неагрегированные столбцы в MySQL не являются частью стандарта SQL и даже не разрешено в MySQL 5.7 и более поздних версий, если не изменено значение по умолчанию для режима ONLY_FULL_GROUP_BY.

В более ранних версиях результат недетерминирован.

The server is free to choose any value from each group, so unless they are the same, the values chosen are nondeterministic. Furthermore, the selection of values from each group cannot be influenced by adding an ORDER BY clause.

Это означает, что невозможно было узнать, какие строки будут возвращены этим запросом:

SELECT S1.ID,S1.Template_ID,S1.Assigned_By,S1.Assignees,S1.Active 
FROM "Schedule" AS S1
GROUP BY Template_ID;

Чтобы получить детерминированные результаты, вам понадобится способ ранжировать строки с помощью функции ранжирования, введенного в MySQL 8, например ROW_NUMBER(). Это уже доступно в SQL Server, по крайней мере, начиная с SQL Server 2012. Синтаксис одинаков для обеих баз данных:

WITH ranked as AS 
(
    SELECT 
        ID,Template_ID,Assigned_By,Assignees Active, 
        ROW_NUMBER(PARTITION BY Template_ID Order BY ID)
    FROM Scheduled
    WHERE Assignees IN(6, 3) 
)
SELECT ID,Template_ID,Assigned_By,Assignees Active
FROM ranked
Where RN=1

PARTITION BY Template_ID разбивает строки результатов на основе их Template_ID значения на отдельные разделы. В этом разделе строки упорядочены на основе предложения ORDER BY. Наконец, ROW_NUMBER вычисляет номер строки для каждой упорядоченной строки раздела.

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