如何将一条记录拆分为两条并设置空值?

时间:2012-11-04 22:24:58

标签: sql sql-server stored-procedures

我有以下记录:

Id    Date          MondayMorning  MondayEvening  TuesdayMorning TuesdayEvening and so on
1   2012-01-01          2               3               2              2
2   2012-01-02          2               2               2              2

我希望在两个记录中分成记录1,因为星期一和星期一的状态不一样。如果状态相同则不做任何事情。

我期待的结果:

Id    Date          MondayMorning  MondayEvening  TuesdayMorning  TuesdayEvening
1   2012-01-01          2               NULL          2                 2
1   2012-01-01          NULL            3             NULL              NULL
2   2012-01-02          2               2             2                 2

请记住,其他日子也可能有所不同。

我已经有了查询但是,有些更改。查看查询 SQL Fiddle。 您可以在此处看到的输出是出错的情况。对于星期二晚上和星期一晚上我期待2。

关于SQL Fiddle的信息是:

Declare @t Table(Id int identity,[Date] Datetime,MondayMorning Int,MondayEvening Int,TuesdayMorning Int,TuesdayEvening Int)
Insert Into @t Select '2012-01-01',0,2,0,2

SELECT id
    ,date
    ,MondayMorning
    ,(CASE WHEN MondayEvening <> MondayMorning THEN NULL ELSE MondayEvening END) AS MondayEvening
    ,TuesdayMorning
    ,(CASE WHEN TuesdayEvening <> TuesdayMorning THEN NULL ELSE TuesdayEvening END) AS TuesdayEvening
FROM @t 

UNION ALL 

SELECT id
    ,date
    ,NULL AS MondayMorning
    ,(CASE WHEN MondayEvening = MondayMorning THEN NULL ELSE MondayEvening END) AS MondayEvening
    ,NULL AS TuesdayMorning
    ,(CASE WHEN TuesdayEvening = TuesdayMorning THEN NULL ELSE TuesdayEvening END) AS TuesdayEvening
FROM @t
WHERE --MondayMorning <> MondayEvening
--OR TuesdayMorning <> TuesdayEvening
MondayMorning <> MondayEvening
AND (MondayMorning != 0 and MondayEvening != 0)
OR TuesdayMorning <> TuesdayEvening
AND (TuesdayEvening != 0 and TuesdayMorning != 0)

1 个答案:

答案 0 :(得分:1)

SQL Server 2008+,使用VALUES优雅地构造子查询。

Declare @t Table(Id int identity,[Date] Datetime,MondayMorning Int,MondayEvening Int,TuesdayMorning Int,TuesdayEvening Int)
Insert Into @t Select '2012-01-01',0,2,3,2

     SELECT t.Id, t.[Date],
            Case when MondayMorning=v.state then MondayMorning end MondayMorning,
            Case when MondayEvening=v.state then MondayEvening end MondayEvening,
            Case when TuesdayMorning=v.state then TuesdayMorning end TuesdayMorning,
            Case when TuesdayEvening=v.state then TuesdayEvening end TuesdayEvening
       FROM @t t
CROSS APPLY (select distinct State
               from (values(MondayMorning),
                           (MondayEvening),
                           (TuesdayMorning),
                           (TuesdayEvening)) v(state)) v(state)

在SQL Server 2005上,将VALUES()派生表替换为SELECT .. UNION ALL,例如

CROSS APPLY (select distinct State
               from (SELECT MondayMorning UNION ALL
                     SELECT MondayEvening UNION ALL
                     SELECT TuesdayMorning UNION ALL
                     SELECT TuesdayEvening) v(state)) v(state)