SQL Server: как суммировать значения столбца, если имя столбца содержит слово? - PullRequest
1 голос
/ 25 июня 2010

В моей таблице SQL:

Period| Brand A small Bags| Brand A big bags| Brand D Shoes| ...|  Brand X Shoes
2010  |   10              | 20              | 30           | ...| 200           

Как суммировать столбцы, содержащие определенные слова (например, обувь) в именах столбцов?

Ожидаемые результаты:

Period | Sum of Bags | Sum of Shoes | ..
2010   | 30          | 230          | ..

Ответы [ 4 ]

10 голосов
/ 25 июня 2010

Нельзя обойтись без динамического SQL и запроса таблиц information_schema или его жесткого кодирования. Можете ли вы реструктурировать свои данные, например, следующим образом?

Brands (BrandId, BrandName)
ItemTypes (ItemId, ItemName)
Stock(BrandId, ItemId, Period, Quantity)

Редактировать

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

  • Максимальное количество столбцов в таблице - 1024, поэтому вы не можете продолжать добавлять столбцы для каждой перестановки бренда / элемента, которая когда-либо происходит.

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

  • Вы не можете выполнять простые вычисления, такие как суммирование всех сумок, без жесткого кодирования всех перестановок и не забудьте обновить этот код при добавлении нового бренда.

  • Вы не можете выполнять некоторые запросы вообще (или, по крайней мере, не без особых затруднений) - например, возвращать названия всех брендов, поставляющих обувь.

2 голосов
/ 25 июня 2010

Нельзя использовать подстановочные знаки в именах столбцов (только для содержимого).

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

select period, sum([Brand A small bags]) + sum([Brand A big bags]) as [sum of bags],
   sum([Brand D shoes]) + sum([Brand X shoes]) as [sum of shoes]
from yourtable
group by period

Но было бы лучше реструктурировать ваши данные, как предлагает Мартин Смит.

1 голос
/ 27 июня 2010

Что ж, я хотел попытаться решить эту проблему в качестве упражнения для себя, потому что я изучаю SQL более подробно.Я думаю, что проблемы с данной схемой достаточно хорошо задокументированы, чтобы я больше ничего об этом не говорил.

Чтобы этот код работал, столбцы в исходных данных должны быть физическими столбцы (т. е. не табличная переменная или столбцы в представлении).Вы можете абстрагировать этот код в функции и еще много чего, если есть больше типов, чем просто сумки и обувь.Я просто хотел разобраться с алгоритмическими вещами.Есть много других предостережений для правильной работы, но, как уже упоминалось, денормализованные данные также имеют полный набор предостережений.

Итак, мы идем:

РЕДАКТИРОВАТЬ: Версия 2. Спасибо Мартину за помощь в этом.Это действительно изящный трюк, хотя, вероятно, его нужно использовать редко.

Я предполагаю, что имена столбцов будут соответствовать шаблону поиска (он достаточно жестко задан, поэтому зачем проверять).

DECLARE @sql nvarchar(max)
SET @sql = 'SELECT Period, '


-- Build column sum for bags
DECLARE @bagsColumns nvarchar(max)

SELECT
    @bagsColumns = COALESCE(@bagsColumns + '+', N'') + '[' + COLUMN_NAME + ']'
    FROM INFORMATION_SCHEMA.COLUMNS
    WHERE TABLE_NAME = 'SumTest' AND COLUMN_NAME LIKE '%bags%'

SET @sql = @sql + @bagsColumns + ' AS ''Sum of Bags'', '


-- Build column sum for shoes
DECLARE @shoesColumns nvarchar(max)

SELECT
    @shoesColumns = COALESCE(@shoesColumns + '+', N'') + '[' + COLUMN_NAME + ']'
    FROM INFORMATION_SCHEMA.COLUMNS
    WHERE TABLE_NAME = 'SumTest' AND COLUMN_NAME LIKE '%shoes%'

SET @sql = @sql + @shoesColumns + ' AS ''Sum of Shoes'''


SET @sql = @sql + ' FROM SumTest'

EXEC(@sql)
0 голосов
/ 25 июня 2010
SELECT PERIOD, [Brand A small Bags] + [Brand A big bags] [Sum of Bags] ... etc
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...