Я новичок в 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 не было проблем с GroupBy. Я пытаюсь понять, как SQL извлекает идентификаторы с помощью Group By
да, это так, и я только что разместил ссылку на Документы MySQL, которая объясняет это. Вы использовали неподдерживаемый хак. Раньше у вас был неверный запрос, который приводил к MySQL 5.7. это все еще плохой запрос в SQL Server или любой другой базе данных. В более старых версиях MySQL вы получали случайные значения вместо первой строки.
group by
для агрегации, я думаю, вы хотите использовать оконная функция, чтобы получить номер строки и взять первую строку для каждого template_id?
@ Дейл Баррелл, да. У меня была ошибка агрегации, а затем я попробовал этот запрос
@Зенди, что ты хочешь сделать? Почему вы хотите использовать GROUP BY, если хотите вернуть все столбцы? Даже в MySQL поддерживается способ использования ROW_NUMBER()
или одной из других функций ранжирования, представленных в MySQL 8.0.
@Zendie, вы должны знать, что, поскольку это не поддерживается, MySQL не проверяет его поведение. Запросы с неагрегированными столбцами в MySQL 5.7 выполняются намного хуже, чем в более ранних версиях.
@Зенди из 5.6 документыThe server is free to choose any value from each group, so unless they are the same, the values chosen are nondeterministic.
Я хочу вернуть только одну строку из таблицы, в которой пользователь принадлежит к группе (то есть назначенным)
@Zendie только одна строка по каким критериям? Случайный? Самый маленький идентификатор?
@PanagiotisKanavos ВЫБЕРИТЕ ИДЕНТИФИКАТОР_шаблона ИЗ «Расписания», ГДЕ «Уполномоченные» В (6, 3) СГРУППИРОВАТЬ ПО «ИДЕНТИФИКАТОРу_шаблона»; Это именно то, что я хочу сделать, но для этого результата мне нужны и другие значения столбца. Наименьший идентификатор будет отображаться
Если Template_ID = 25, это соответствует 2 строкам, но вы хотите отобразить только одну строку, но хотите отобразить все значения. Вы понимаете, почему мы в замешательстве? Если вы хотите отобразить все значения без агрегирования, вам нужно выбрать строку.
Мы подозреваем, что вы хотите выбрать строку с наименьшим идентификатором, и в этом случае ответом является оконная функция, на которую я ссылался в предыдущем комментарии.
@DaleBurrell Спасибо, я посмотрю оконную функцию. Мне нужно сгруппировать записи по TemplateID. И необходимо отображать значения самого низкого идентификатора, назначенного и активного значения.
Если вы хотите сгруппировать и показать самые низкие значения, просто используйте функцию min
Запрос не работает должным образом и в 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
вычисляет номер строки для каждой упорядоченной строки раздела.
Запрос, который вы запрашиваете, — недействителен даже в MySQL. Однако вы работали с синтаксисом не поддерживается, который выдает ошибку в последних версиях и возвращает случайные результаты в более ранних версиях — в таблице или запросе нет неявного порядка, если только он не указан
ORDER BY
, поэтому сервер вернет первое значение, возвращенное выполнением запроса.