【问题标题】:SQL Server 2008 R2 – Reducing multiple rows into oneSQL Server 2008 R2 – 将多行减少为一行
【发布时间】:2015-01-15 14:40:44
【问题描述】:

我需要让我的数据在一行中显示个人在过去 3 年内是否有'完成'特定课程。

这是我的 existing 表和 desired 表(希望此链接有效,因为我还不能发布图片!): http://i.stack.imgur.com/c8oJO.png

我试过这段代码:

SELECT DISTINCT
EN,
(First_Name + ' ' + Last_Name) as Name,

First_Aid = CASE
WHEN Course = 'First Aid' 
and Status = 'Finished'
and Course_Start_Date > DATEADD(day, -1095, GETDATE())
THEN 'F'
ELSE 'Nope'
END,

Manual_Handling = CASE
WHEN Course = 'Manual Handling'
and Status = 'Finished'
and Course_Start_Date > DATEADD(day, -1095, GETDATE())
THEN 'F'
ELSE 'Nope'
END,

Fire_Safety = CASE
WHEN Course = 'Fire Safety'
and Status = 'Finished'
and Course_Start_Date > DATEADD(day, -1095, GETDATE())
THEN 'F'
ELSE 'Nope'
END
into MyTraining
FROM Learning_History`

这会产生准确的结果,但每个 CASE 语句都有一个单独的行(加上一个包含所有“否”结果的额外行)。所以我尝试了这段代码:

SELECT 
EN,
(First_Name + ' ' + Last_Name) as Name,

First_Aid =MAX(CASE
WHEN Course = 'First Aid' 
and Status = 'Finished'
and Course_Start_Date > DATEADD(day, -1095, GETDATE())
THEN 'F'
ELSE 'Nope'
END),

Manual_Handling =MAX(CASE
WHEN Course = 'Manual Handling' 
and Status = 'Finished'
and Course_Start_Date > DATEADD(day, -1095, GETDATE())
THEN 'F'
ELSE 'Nope'
END),

Fire_Safety =MAX(CASE
WHEN Course = 'Fire Safety' 
and Status = 'Finished'
and Course_Start_Date > DATEADD(day, -1095, GETDATE())
THEN 'F'
ELSE 'Nope'
END)

into MyTraining
FROM Learning_History

Group By EN,First_Name, Last_Name

此代码确实产生 1 行 - 但所有结果都是“不”。

我不太了解这方面的内容(只是在 Google 上搜索了大部分代码),因为我是 SQL 的初学者(所以我可能犯了一些简单的错误)。我认为数据透视表可能是要走的路 - 但我无法理解它们......

【问题讨论】:

    标签: sql-server sql-server-2008-r2 case select-case


    【解决方案1】:

    您可以像您正在尝试的那样使用 PIVOT 或 case 和 group by 来做到这一点。

    PIVOT 示例:

    select
        EN,
        [First Aid],
        [Manual Handling],
        [Fire Safety]
    from (
        select
            [EN],
            [Course],
            [Status]
        from (
            select
                ROW_NUMBER() OVER (
                    PARTITION BY
                        EN,Course
                    ORDER BY
                        Course_Start_Date
                ) rID,
                *
            from (
                select
                *
                from (
                    values
                        (1,'First Aid','1999-06-22','Finished'),
                        (1,'First Aid','2013-02-19','Finished'),
                        (1,'Manual Handling','2014-02-10','Cancelled'),
                        (1,'Manual Handling','2014-03-20','Finished'),
                        (1,'Fire Safety','2099-07-29','Finished'),
                        (1,'Fire Safety','2014-11-19','No Show')
                ) myTable ([EN],[Course],[Course_Start_Date],[Status])
            ) myTable
        )T
        where
            rID = 1
    ) S
    PIVOT (
        MAX(Status) FOR Course IN ([First Aid],[Manual Handling],[Fire Safety])
    ) PVT
    

    PS.: 我假设 EN 是 PRIMARY KEY

    编辑:再试一次,)

    【讨论】:

    • 感谢 mxix。我不太了解这个,但我让它运行正常。不过,它似乎没有检查课程开始日期。此外 - 它返回 41000 行,而原始表中这 3 门课程只有 4000 行。谢谢你'
    • 感谢 mxix。不能让这个为我工作。我不了解数据透视表,所以无法弄清楚发生了什么。不过感谢您的帮助。我现在发现,如果我去掉我的案例陈述中的“Else..”部分,它就会在一行中起作用。不是我想要的——但会坚持使用这段代码。
    猜你喜欢
    • 2020-11-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-03
    • 2011-04-20
    • 2016-03-29
    • 2016-03-20
    相关资源
    最近更新 更多