Каковы некоторые хорошие способы переноса данных в таблице SQL из строк-столбцов в столбцы-столбцы?

Каковы некоторые хорошие способы переноса данных в таблице SQL из строк-столбцов в столбцы-столбцы?

Также разрешает фильтры/условия, которые должны применяться к исходному запросу.

Использование SQL Server 2008.

Существующие таблицы имеют следующие столбцы: AID (уникальный nvarchar) ASID (уникальный nvarchar) Веха (M1, M2, M3 ... M100) MilestoneDate (дата и время)

Транспонированные данные: AID, ASID, M1 Дата, M2 Дата, M3 Дата, M5 Дата

0
добавлено отредактировано
Просмотры: 1
de
Какие RDBMS вы используете? Эти вещи сильно для конкретного поставщика - и SQL - это только язык структурированных запросов, а не продукт базы данных ...
добавлено автор marc_s, источник
Если это mysql, я прочитал неплохую статью о сводных таблицах здесь: ru.wikibooks.org/wiki/ MySQL/Pivot_table . Это также должно помочь некоторым другим rdbms.
добавлено автор piotrekkr, источник
Как правило, вы должны использовать операторы CASE или PIVOT , но трудно понять, что более подходит без каких-либо деталей в вашем вопросе. Если бы вы могли наметить проблему с примерами таблиц и данных, это будет иметь больше смысла.
добавлено автор Ciarán, источник

2 ответы

Если вы используете SQL Server 2005+, у вас есть несколько вариантов переноса данных. Вы можете реализовать функцию PIVOT , подобную этой:

select AID, ASID, 
  M1 as M1_Date, M2 as M2_Date, 
  M3 as M3_Date, M4 as M4_Date, M5 as M5_Date
from 
(
  select AID, ASID, Milestone,
    MilestoneDate
  from yourtable
  where AID = whatever -- other filters here
) src
pivot
(
  max(milestonedate)
  for milestone in (M1, M2, M3, M4, M5...)
) piv

Или вы можете использовать агрегированную функцию с выражением CASE :

select aid, 
  asid, 
  max(case when milestone = 'M1' then milestonedate else null end) M1_Date,
  max(case when milestone = 'M2' then milestonedate else null end) M2_Date,
  max(case when milestone = 'M3' then milestonedate else null end) M3_Date,
  max(case when milestone = 'M4' then milestonedate else null end) M4_Date
from yourtable
where AID = whatever -- other filters here 
group by aid, asid

Вышеупомянутые два запроса отлично работают, если у вас есть известное количество значений milestone . Но если нет, то вы можете реализовать динамический sql для переноса данных. Динамическая версия будет похожа на следующую:

DECLARE @cols AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX),
    @colNames AS NVARCHAR(MAX),

select @cols = STUFF((SELECT distinct ',' + QUOTENAME(Milestone) 
                    from yourtable
            FOR xml PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

select @colNames = STUFF((SELECT distinct ',' + QUOTENAME(Milestone+'_Date') 
                    from yourtable
            FOR xml PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT AID, ASID,' + @colNames + ' from 
             (
                select AID, ASID, Milestone,
                  MilestoneDate
                from yourtable
                where AID = whatever -- other filters here 
            ) x
            pivot 
            (
                max(MilestoneDate)
                for Milestone in (' + @cols + ')
            ) p '

execute(@query)
7
добавлено

Это довольно общий подход:

select 
aid, asid, 
max (case when milestone = 'M1' then milestonedate else null end) M1Date,
max (case when milestone = 'M2' then milestonedate else null end) M2Date,
max (case when milestone = 'M3' then milestonedate else null end) M3Date,
max (case when milestone = 'M5' then milestonedate else null end) M5Date
from
mytable
group by aid, asid
4
добавлено