Итак, у меня есть следующая таблица:
Name Value
A 10
ABC 5
A 8
ABC 3
AB 2
И я хочу этот результат:
Name Value
A 28
AB 10
ABC 8
Поэтому я хочу группировать не по точному совпадению с именем, а по начальным символам. Является ли это возможным?
Привет, с ними обоими. Тогда группа AB также должна содержать значения ABC и ABD.
Пожалуйста, отметьте вашу версию РСУБД
Рекурсивно ли это через строки из 4-n символов, т.е. группировка по первым 3 символам, затем по 4 символам и т. д.?
Всего 3 символа и всегда в алфавитном порядке.
С SQL Server 2022:
SELECT LEFT("Name", "value") AS STRING, SUM("Value") AS TOTAL
FROM SoIHaveTheFollowingTable
CROSS APPLY GENERATE_SERIES(1, CASE WHEN LEN("Name") > 3 THEN 3 ELSE LEN("Name") END)
GROUP BY LEFT("Name", "value")
ORDER BY STRING;
ПРИМЕЧАНИЕ: с регистрозависимой сортировкой базы данных из-за двух столбцов с именами «Значение» и «значение»... Поскольку вы никогда не должны использовать идентификаторы SQL, которые являются зарезервированными словами (значение, имя, тип, дата...)
Для версии < 2022 сначала используйте рекурсивный запрос, чтобы сгенерировать серию значений int.
Зачем использовать рекурсивный запрос в 2019 году или ранее, а не просто подсчет? Согласно комментариям, в OP есть только строки длиной до 3 символов, поэтому добавление рекурсии было бы значительным накладным расходом для чего-то, что на самом деле в ней не нуждается.
Кроме того, вместо того, чтобы догадываться, что OP использует сопоставление с учетом регистра (что, я думаю, маловероятно), вам действительно следует использовать псевдонимы и квалифицировать свои столбцы.
@larnu Потому что Роб Дон не соблюдает правила публикации, не предоставляя DDL таблиц ...
Я не уверен, почему отсутствие DDL является причиной для использования более медленного решения или причиной для того, чтобы не квалифицировать ваши объекты, @SQLPro . Как SQL Pro, вы должны знать важность псевдонимов и квалификации.
@larnu Медленнее? Считаете ли вы, что сортировка BINARIES медленнее? Я постоянно доказываю обратное на своих курсах для профессиональных и инженерных школ...
Я знаю, что рекурсия медленнее, чем основанная на наборах @SQLPro .
Вы можете использовать UNION
для каждого количества символов, по которым вы хотите сгруппировать. Что-то вроде этого:
SELECT cat, SUM(val) num FROM (
SELECT SUBSTRING(Name,1,1) cat, SUM(Value) val FROM table GROUP BY cat
UNION ALL
SELECT SUBSTRING(Name,1,2) cat, IF(LENGTH(Name)>1, SUM(Value), 0) val FROM table GROUP BY cat
UNION ALL
SELECT SUBSTRING(Name,1,3) cat, IF(LENGTH(Name)>2, SUM(Value), 0) val FROM table GROUP BY cat
) a
GROUP BY cat
ORDER BY cat
IF
-оператор длины строки предотвращает включение сумм для строк короче, чем длина, которую вы хотите вычислить.
Результат
+──────+─────+
| cat | num |
+──────+─────+
| A | 28 |
| AB | 10 |
| ABC | 8 |
+──────+─────+
@Michael_Krikorev По соображениям производительности вы должны использовать UNION ALL вместо UNION.... Голосуйте -1
@SQLpro спасибо за отзыв. Результаты должны быть одинаковыми. Я обновил ответ на UNION ALL
вместо UNION
Запрос различается в зависимости от того, включает ли результат non-existent character data
(например, «B» не существует для «BC»).
Если вы используете рекурсивный запрос, результат будет содержать non-existent character data
.
WITH cte as (
SELECT SUBSTRING(Name,1,3) Name, SUM(Value) Value FROM Table1
GROUP BY SUBSTRING(Name,1,3)
UNION ALL
SELECT SUBSTRING(Name,1,LEN(Name)-1), Value FROM cte
WHERE LEN(Name)>1
)
SELECT Name, SUM(Value) FROM cte
GROUP BY Name
ORDER BY Name
Если вы используете присоединенные подзапросы, результат не будет содержать non-existent character data
.
WITH cte as (
SELECT SUBSTRING(Name,1,3) Name, SUM(Value) Value FROM Table1
GROUP BY SUBSTRING(Name,1,3)
)
SELECT
t1.Name,
SUM(t2.Value)
FROM cte t1 JOIN cte t2
ON t1.Name=SUBSTRING(t2.Name,1,LEN(t1.Name))
GROUP BY t1.Name
ORDER BY t1.Name
Пример с дополнительными данными: db fiddle
Если Name
— это 3 символа, SUBSTRING(Name,1,3)
— это просто Name
.
См. следующее.
Пример с дополнительными данными: db fiddle
в требованиях говорится, что это только для 3 первых символов, а не для всей длины строки... голосование -1
ОП подтвердил, что это будет не более 3 символов, @SQLpro.
@larnu Он подтвердил, что исчисление будет выполняться только для 3 символов, никогда не говорит, что все строки имеют длину 3 символа ... Если он будет соблюдать правила публикации, указав DDL таблицы, мы сможем увидеть, является ли этот столбец это СИМВОЛ(3)...
Я хотел бы видеть больше данных. Если бы ваши данные имели значение
ABD
, было быAB
сгруппировано сABC
илиABD
?