条件字符串串联的 T-SQL 查询

T-SQL query for conditional string cocatenation

提问人:junyong lee 提问时间:10/17/2023 最后编辑:Joel Coehoornjunyong lee 更新时间:10/17/2023 访问量:72

问:

人员 ID 名字 结果日期 类别名称 种类Value
569 一个 2015-11-10 注意
569 一个 2015-11-10 结果 通过
569 一个 2015-11-10 得分 16
585 B 2015-11-09 注意 你好!
585 B 2015-11-09 结果 失败
585 B 2015-11-09 得分 8
585 B 2020-03-01 注意
585 B 2020-03-01 结果 通过
585 B 2020-03-01 得分 10

我在 SQL Server 中有此考试结果表。

每个行可以有多个行,并且每个行的值始终为 、 和 。PersonIDResultDateResultDateCategoryNameNoteResultScore

我想连接其为 和 的列,所以我有一个格式。CategoryValuesCategoryNameResultScoreResult(Score)

例如,对于 2015-11-10 上的 PersonID 569,我希望看到 .对于 PersonID 585,我希望看到 2015-11-09 和 2020-03-01 的“Failed(8)”。Passed(16)Passed(10)

我怎样才能做到这一点?

我尝试过使用条件查询的 STRING_AGG 和 CONCAT,但失败了。

sql-server 字符串串联

评论

0赞 topsail 10/17/2023
您想要的结果不清楚。“对于 PersonID 585,我希望看到 2015-11-09 的 'Failed(8)',以及 2020-03-01 的 'Passed(10)'。” - 这应该是单个字符串,还是返回两个单独的记录?日期应该是结果的一部分吗?
1赞 Thom A 10/17/2023
为什么不将数据存储在更规范的视图中?虽然这看起来像一个 EAV 设计,但因此,在应用程序中执行与“Englishfy”值的串联会更好。
2赞 Stu 10/17/2023
与其描述您想要的结果,不如将其作为表格数据包括在内,例如,您是否正在为示例数据添加额外的列?别的?
0赞 Eric 10/17/2023
“我试过STRING_AGG和CONCAT......”哪里???我们在查询中看不到您的尝试。如果您不发布查询,我们该如何帮助您???

答:

0赞 FriendlyDragon 10/17/2023 #1

试试这样的事情。这很简单,但很清楚,对我来说=)

with r as (
  select distinct PersonID, Name, ResultDate
  from mytable
)
select   r.*
         , concat((select CategoryValue from mytable where personId=r.PersonId and resultDate=r.resultDate and CategoryName='Result')
          , ' (', (select CategoryValue from mytable where personId=r.PersonId and resultDate=r.resultDate and CategoryName='Score'), ')') result
from     r

https://dbfiddle.uk/h-hfU2Z2

1赞 siggemannen 10/17/2023 #2

您可以将STRING_AGG与 CONCAT 一起使用,但它有点不漂亮:

select personid,name, ResultDate
, string_agg(CONCAT(CategoryValue, case when CategoryName = 'Result' THEN ' (' ELSE ')' END), '') WITHIN GROUP (ORDER BY case when CategoryName = 'Result' THEN 0 ELSE 1 END) AS Result
from (
    VALUES  (569, N'A', N'2015-11-10', N'Note', NULL)
    ,   (569, N'A', N'2015-11-10', N'Result', N'Passed')
    ,   (569, N'A', N'2015-11-10', N'Score', N'16')
    ,   (585, N'B', N'2015-11-09', N'Note', N'Hello!')
    ,   (585, N'B', N'2015-11-09', N'Result', N'Failed')
    ,   (585, N'B', N'2015-11-09', N'Score', N'8')
    ,   (585, N'B', N'2020-03-01', N'Note', NULL)
    ,   (585, N'B', N'2020-03-01', N'Result', N'Passed')
    ,   (585, N'B', N'2020-03-01', N'Score', N'10')
) t (PersonID,Name,ResultDate,CategoryName,CategoryValue)
WHERE CategoryName IN ('Result', 'Score')
group by personid, name, resultDate

输出:

personid(人际ID) 名字 结果日期 结果
569 一个 2015-11-10 通过 (16)
585 B 2015-11-09 失败 (8)
585 B 2020-03-01 通过 (10)

评论

0赞 junyong lee 10/18/2023
这解决了我尝试使用 STRING_AGG 和 CONCAT 的问题。不能这样想。谢谢。
0赞 Joel Coehoorn 10/17/2023 #3

试试这个:

SELECT r0.PersonID, r0.Name, r0.ResultDate
   , MIN(r0.CategoryValue) + '(' + MIN(r1.CategoryValue) + ')' As Result
FROM ExamResults r0
INNER JOIN ExamResults r1 ON r1.PersonID = r0.PersonID AND r1.ResultDate = r0.ResultDate
   AND r1.CategoryName = 'Score'
WHERE r0.CategoryName = 'Result'
GROUP BY r0.PersonID, r0.Name, r0.ResultDate

在这里看到它的工作:

https://dbfiddle.uk/AEWDZq1k

0赞 Avisekh Lal 10/17/2023 #4

试试这个,例如使用String_agg

SELECT STRING_AGG(ConcatenatedValues, ' and  ') AS result
FROM (
    SELECT
        PersonID,
        concat( STRING_AGG(CategoryValue, ', '), ' for ',ResultDate) AS 
        ConcatenatedValues
    FROM ExamResult
WHERE CategoryName IN ('Result', 'Score') AND PersonID = 585
GROUP BY PersonID, ResultDate) a