在加入

时间:2016-11-15 13:06:49

标签: sql sql-server

我有以下表格:

declare @Risks table(id int identity, name varchar(20))
declare @Mitigations table(id int identity, riskId int, mitigation_desc varchar(20), record_date datetime)

insert into @Risks(name)
select 'Risk 1' union all
select 'Risk 2' union all
select 'Risk 3'

insert into @Mitigations(riskId, mitigation_desc, record_date)
select 1, 'Mitigation 1', '2016-01-01' union all
select 1, 'Mitigation 2', '2016-01-01' union all
select 2, 'Mitigation 3', '2016-01-01' 

SELECT  *
FROM    @Risks a
LEFT OUTER JOIN  @Mitigations b ON a.id = b.riskId

每个风险可以有多于1个缓解,没有限制,我想做的是能够像这样水平显示每个风险的所有缓解:

ID  Name   mitigation_desc      record_date   mitigation_desc  record_date 
--- -----  ------------------  -------------  ---------------- -------------
1   Risk 1  Mitigation 1        2016-01-01    Mitigation 2       2016-01-01
2   Risk 2  Mitigation 3        2016-01-01    NULL               NULL
3   Risk 3  NULL                NULL          NULL               NULL

我尝试了一些使用支点和连接的场景,但没有一个是足够灵活的,因为风险可以有多少缓解。有没有其他方法可以实现这个目标?

为了方便起见,我可以限制显示的缓解措施的数量,例如,每个风险总是显示3组缓解措施。

由于

1 个答案:

答案 0 :(得分:1)

如果您只想返回最多两个缓解,那么我将使用以下内容......

WITH
   sorted_risks AS
(
    SELECT
        ROW_NUMBER() OVER (PARTITION BY riskID
                               ORDER BY record_date,
                                        mitigation_desc)  AS ordinal,
        *
    FROM
        @risks
)
SELECT
    riskID,
    MAX(CASE WHEN ordinal = 1 THEN mitigation_desc END)   AS mitigation_desc_1,
    MAX(CASE WHEN ordinal = 1 THEN record_date     END)   AS record_date_1,
    MAX(CASE WHEN ordinal = 2 THEN mitigation_desc END)   AS mitigation_desc_2,
    MAX(CASE WHEN ordinal = 2 THEN record_date     END)   AS record_date_2
FROM
    sorted_risks
WHERE
    ordinal <= 2
GROUP BY
    riskID

如果您想要最新的两个(而不是最早的两个)记录,请将ORDER BY record_date,更改为ORDER BY record_date DESC,

即便如此,我仍然建议SQL是错误的做法。

您的评论表明,您只是出于演示原因,在MVC应用程序中执行此操作。在这种情况下,您应该在MVC应用程序的表示层中执行此操作。