Сводка с использованием SQL Server 2000

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

у меня две таблицы

Продукты

альтернативный текст

Мета продукта

альтернативный текст

Мне нужен набор результатов из следующего

альтернативный текст


person sykespro    schedule 23.11.2008    source источник


Ответы (4)


В прошлом мы успешно использовали следующий подход...

SELECT [p].ProductID,
       [p].Name,
       MAX(CASE [m].MetaKey
             WHEN 'A'
               THEN [m].MetaValue
           END) AS A,
       MAX(CASE [m].MetaKey
             WHEN 'B'
               THEN [m].MetaValue
           END) AS B,
       MAX(CASE [m].MetaKey
             WHEN 'C'
               THEN [m].MetaValue
           END) AS C
FROM   Products [p]
       INNER JOIN ProductMeta [m]
         ON [p].ProductId = [m].ProductId
GROUP  BY [p].ProductID,
          [p].Name 

Также может быть полезно транспонировать агрегации с использованием...

SUM(CASE x WHEN 'y' THEN yVal ELSE 0 END) AS SUMYVal

ИЗМЕНИТЬ

Также стоит отметить, что это использует стандартный SQL ANSI, поэтому он будет работать на разных платформах :)

person Rich Andrews    schedule 28.11.2008
comment
Это работает только тогда, когда значения являются статическими, то есть вы заранее знаете значения столбца. - person M.R.; 27.04.2011
comment
одна вещь, которую я не понимаю, это то, что если вам нужно использовать [m].metavalue во всех случаях переключения, то зачем беспокоиться об использовании случая переключения, можете немного объяснить. - person user786; 25.02.2016
comment
Потому что, например, вы хотите, чтобы в столбце а отображалась только сумма [m].metavalue, где [m].metakey равно 'a'. По сути, он отфильтровывает все другие результаты метазначения суммы. Таким образом, вы можете перенести данные из исходных строк в столбцы. - person Rich Andrews; 25.02.2016

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

Select P.ProductId, P.Name
    , Min( Case When PM.MetaKey = 'A' Then PM.MetaValue End ) As A
    , Min( Case When PM.MetaKey = 'B' Then PM.MetaValue End ) As B
    , Min( Case When PM.MetaKey = 'C' Then PM.MetaValue End ) As C
From Products As P
        Join ProductMeta As PM
            On PM.ProductId = P.ProductId
Group By P.ProductId, P.Name

Вы должны использовать Group By, иначе вы получите разнесенный результат. Если вы используете Group By, вы должны обернуть каждый столбец, который не входит в предложение Group By, в агрегатную функцию (или подзапрос).

person Thomas    schedule 27.04.2011
comment
Я только что переработал ужасно медленный сводной запрос, чтобы использовать здесь метод с min(), и улучшил запрос, чтобы он выполнялся менее чем за 2 секунды. Я награждаю вас +2 интернета! - person Kirk; 23.04.2012

Если у вас ядро ​​базы данных 2005 и ваша база данных находится в режиме совместимости с 2000, вы можете обойти более низкий режим совместимости, выполнив запрос из базы данных 2005. Нацельтесь на базу данных 2000, используя соглашение об именах из трех частей для ваших таблиц в запросе, например DatabaseNameHere.dbo.TableNameHere

person AaronLS    schedule 31.03.2010

person    schedule
comment
Спасибо GregD, но боюсь, это мне не поможет. Проблема в том, что когда в таблицу ProductMeta добавляется новая запись, мне придется вернуться и изменить этот оператор. Я стараюсь, чтобы мои очки обслуживания были как можно ниже. - person sykespro; 23.11.2008
comment
А.. Хорошо, тогда вам, вероятно, захочется взглянуть на эту статью: oreillynet.com/pub/a/network/2004/12/17/crosstab.html - person GregD; 24.11.2008