SQL возвращает значения в виде полей на основе таблицы ключей и типов значений - PIVOT, CASE и т. Д.? - PullRequest
0 голосов
/ 04 августа 2011

Используя SQL Server 2005, у меня есть следующие таблицы:

Значение:

ValueID  UserID    ValueTypeID  ValueKey  Text  Number
------------------------------------------------------
1        345       1            NAME      Bob   NULL
2        345       2            AGE       NULL  30
3        689       1            NAME      Sam   NULL
4        689       2            AGE       NULL  45

ValueType:

ValueTypeID  CodeName
---------------------
1            TEXT
2            NUMBER

И я хочу получить такие результаты:

UserID  Name  Age
-----------------
345     Bob   30
689     Sam   45

Я уверен, что это возможно, используя сводку и, возможно, некоторые операторы case?Есть больше ValueKeys, и даже больше ValueTypes, но это поможет мне.Я заранее знаю список ValueKeys, поэтому это должно означать, что я могу избежать динамического запроса.

Ответы [ 3 ]

1 голос
/ 04 августа 2011

Классический сводный запрос. Затем вы можете использовать ValueTypeID, если хотите:

SELECT UserID, 
       MAX(
           CASE WHEN ValueKey = 'NAME' 
                THEN 
                    CASE WHEN ValueTypeID = 1 
                             THEN Text 
                         WHEN ValueTypeID = 2
                             THEN Number 
                         WHEN ValueTypeID = 3
                             THEN Date
                         ELSE NULL
                    END
                ELSE NULL 
           END
       ) AS Name,
       MAX(
           CASE WHEN ValueKey = 'AGE' 
                THEN 
                    CASE WHEN ValueTypeID = 1 
                             THEN Text 
                         WHEN ValueTypeID = 2
                             THEN Number 
                         WHEN ValueTypeID = 3
                             THEN Date
                         ELSE NULL
                    END
                ELSE NULL 
           END
       ) AS Age,
       MAX(
           CASE WHEN ValueKey = 'DATEBIRTH' 
                THEN 
                    CASE WHEN ValueTypeID = 1 
                             THEN Text 
                         WHEN ValueTypeID = 2
                             THEN Number 
                         WHEN ValueTypeID = 3
                             THEN Date
                         ELSE NULL
                    END
                ELSE NULL 
           END
       ) AS DateBirth
FROM Value
GROUP BY UserID

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

SELECT UserID, 
       MAX(
           CASE WHEN ValueKey = 'NAME' 
                THEN Text -- I know that name is a string
                ELSE NULL 
           END
       ) AS Name,
       MAX(
           CASE WHEN ValueKey = 'AGE' 
                THEN Number -- I know that age is a number
                ELSE NULL 
           END
       ) AS Age,
       MAX(
           CASE WHEN ValueKey = 'DATEBIRTH' 
                THEN Date -- I know that date of birth is a date
                ELSE NULL 
           END
       ) AS DateBirth
FROM Value
GROUP BY UserID
0 голосов
/ 04 августа 2011

Вы можете группировать по UserID и использовать подзапрос для получения значений поля.

declare @T table
(
  ValueID int,
  UserID int,
  ValueTypeID int,
  ValueKey varchar(10),
  Text varchar(10),
  Number int
)

insert into @T values
(1,        345,       1,            'NAME',      'Bob',   NULL),
(2,        345,       2,            'AGE',       NULL,    30),
(3,        689,       1,            'NAME',      'Sam',   NULL),
(4,        689,       2,            'AGE',       NULL,    45)

select T1.UserID,
       (select [Text]
        from @T as T2
        where T1.UserID = T2.UserID and
              T2.ValueKey = 'NAME') as Name,
       (select Number
        from @T as T2
        where T1.UserID = T2.UserID and
              T2.ValueKey = 'AGE') as Age
from @T as T1
group by T1.UserID
0 голосов
/ 04 августа 2011

Разрешение должно быть переделать таблицу. Поиск по типу valueType совершенно бесполезен, поскольку реализован. Вы должны просто иметь один столбец «ValueText» вместо «Текст», «Число», ... и хранить все значения в этом 1 столбце. Тогда это будет простое утверждение join.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...