【问题标题】:SQL concat rows with same ID and newest date具有相同 ID 和最新日期的 SQL 连接行
【发布时间】:2016-02-23 15:23:33
【问题描述】:

我正在寻求帮助来查询我的应用程序消息的输出。我有一个查询,它获取每条消息的行并将它们连接在一起形成一个句子。但是我的一些消息号码有两个或更多消息,在这种情况下,我只想要最新日期的消息。我当前的代码通过将每个消息号的行号连接在一起并按 MSG_NUM 的顺序输出它们来输出句子中的所有消息。我已经添加了 MSG_START_DATE 的排序,但正如预期的那样,这仍然给了我两个。如何为每个连接的消息行选择最大值?

以下是我正在使用的字段:

MSG_NUM | MSG_START_DATE  | MSG_LINE_NUM | MSG_TEXT

1       | 2010-01-15      | 1            | Invalid operation
1       | 2010-01-15      | 2            | try again
1       | 2014-02-21      | 1            | Invalid input
1       | 2014-02-21      | 2            | try again

这是我当前的代码:

Select distinct ST2.[MSG_NUM],
substring(
    (
        (Select ' '+LTRIM(RTRIM(ST1.[MSG_TEXT]))  AS [text()]
        From database..messages ST1 
        Where ST1.[MSG_NUM] = ST2.[MSG_NUM]
        ORDER BY ST1.[MSG_START_DATE], ST1.[MSG_LINE_NUM]
        For XML PATH (''),root('xmlchar'), type).value('/xmlchar[1]','varchar(max)')
    ), 2, 2000) [Message]
From database..messages ST2 order by ST2.[MSG_NUM]

这是我收到的输出:

1 无效操作重试 无效输入重试

我只想要输出:

1 无效输入重试

关于如何做到这一点的任何想法?

【问题讨论】:

  • 总是尝试在你的 rdbms 标签中包含 sql 问题 SqlServer, MySql?。某些功能并非在所有数据库上都可用。
  • 已添加! (SQL Server 2012)

标签: sql date sql-server-2012 rows concat


【解决方案1】:

按日期过滤呢?

Select distinct ST2.[MSG_NUM],
substring(
    (
        (Select ' '+LTRIM(RTRIM(ST1.[MSG_LINE_NUM]))  AS [text()]
        From database..messages ST1 
        Where ST1.[MSG_NUM] = ST2.[MSG_NUM]
          AND ST1.[MSG_START_DATE] = (SELECT MAX(ST3.[MSG_START_DATE])
                                      FROM database..messages ST3
                                      WHERE ST2.[MSG_NUM] = ST3.[MSG_NUM]
                                     )
        ORDER BY ST1.[MSG_LINE_NUM]
        For XML PATH (''),root('xmlchar'), type).value('/xmlchar[1]','varchar(max)')
    ), 2, 2000) [Message]
From database..messages ST2 order by ST2.[MSG_NUM]

更好的是,只需在传递给您的查询之前进行过滤

WITH maxd
AS (
    SELECT *
        ,MAX(MSG_START_DATE) OVER (PARTITION BY [MSG_NUM]) AS maxdate
    FROM DATABASE..messages
    )
    ,filter
AS (
    SELECT *
    FROM maxd
    WHERE MSG_START_DATE = maxdate
    )
SELECT DISTINCT ST2.[MSG_NUM]
    ,substring((
            (
                SELECT ' ' + LTRIM(RTRIM(ST1.[MSG_LINE_NUM])) AS [text()]
                FROM filter ST1
                WHERE ST1.[MSG_NUM] = ST2.[MSG_NUM]
                ORDER BY ST1.[MSG_LINE_NUM]
                FOR XML PATH('')
                    ,root('xmlchar')
                    ,type
                ).value('/xmlchar[1]', 'varchar(max)')
            ), 2, 2000) [Message]
FROM filter ST2
ORDER BY ST2.[MSG_NUM]

【讨论】:

  • 哇!做到了!谢谢!我确实犯了一个小错误, LTRIM(RTRIM(ST1.[MSG_LINE_NUM])) 实际上应该是 [MSG_TEXT] 但谢谢谢谢!其余的工作!
  • 你用的是第一版还是第二版?
  • 我都试过了,最后还是第一个。第二个在我取消之前花了两分钟多的时间执行。
猜你喜欢
  • 2015-08-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-12
  • 2022-01-21
  • 2018-06-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多