一尘不染

SQL中STRING_AGG的替代方法

sql

我有一张桌子,如下

| activityName | UserID | deviceID | createdDate             |
|------------------------------------------------------------|
| ON           | 1      | adddsad  |2020-01-09 00:02:59.477  |
| OFF          | 1      | adddsad  |2020-01-09 00:50:39.857  | 
| ON           | 2      | bdddsad  |2020-01-09 00:51:11.480  |
| OFF          | 2      | bdddsad  |2020-01-09 00:51:19.450  |

当我这样使用时STRING_AGG,它是准确的并返回期望的结果

SELECT STRING_AGG(activityName + ' - ' + CONVERT(varchar, createdDate), ' | ') AS tag,
       deviceID,
       UserID
FROM (SELECT tag,
             deviceID,
             UserID
      FROM tbl_DailyLogMaster
      WHERE CONVERT(date, createdDate) = CONVERT(date, GETDATE())
      GROUP BY userID) a
GROUP BY UserID;

它会像这样返回

| tag                                                           | deviceID  | UserID |
|------------------------------------------------------------------------------------|
| ON - 2020-01-09 00:02:59.477 | OFF - 2020-01-09 00:50:39.857  | adddsad   | 1      |
| ON - 2020-01-09 00:51:11.480 | OFF - 2020-01-09 00:51:19.450  | bdddsad   | 2      |

在生产环境中,我正在运行SQL Server 2014,并且不得不处理 STRING_AGG 旧版本不支持的替代项

这是我创造的选择

SELECT deviceID,
       UserID,
       STUFF((SELECT activityName + ' - ' + CONVERT(varchar, createdDate)
              FROM tbl_DailyLogMaster
              WHERE userID = tbl_DailyLogMaster.UserID
                AND CONVERT(date, createdDate) = CONVERT(date, GETDATE())
              ORDER BY UserID
             FOR XML PATH('')),1,1,'') AS tag
FROM tbl_DailyLogMaster
WHERE CONVERT(date, createdDate) = CONVERT(date, GETDATE())
GROUP BY UserID,
         deviceID,
         UserID,
         createdDate,
         activityName;

它像这样返回

| tag                                                                                                                                | deviceID  | UserID |
|---------------------------------------------------------------------------------------------------------------------------------------------------------|
| N - Jan  9 2020 12:51AMOFF - Jan  9 2020 12:51AMON - Jan  9 2020 12:02AMOFF - Jan  9 2020 12:50AM | OFF - 2020-01-09 00:50:39.857  | adddsad   | 1      |
| N - Jan  9 2020 12:51AMOFF - Jan  9 2020 12:51AMON - Jan  9 2020 12:02AMOFF - Jan  9 2020 12:50AM | OFF - 2020-01-09 00:50:39.857  | adddsad   | 1      |
| N - Jan  9 2020 12:51AMOFF - Jan  9 2020 12:51AMON - Jan  9 2020 12:02AMOFF - Jan  9 2020 12:50AM | OFF - 2020-01-09 00:50:39.857  | bdddsad   | 2      |
| N - Jan  9 2020 12:51AMOFF - Jan  9 2020 12:51AMON - Jan  9 2020 12:02AMOFF - Jan  9 2020 12:50AM | OFF - 2020-01-09 00:50:39.857  | bdddsad   | 2      |

我第二次查询做错了什么?


阅读 411

收藏
2021-03-17

共1个答案

一尘不染

一些盲目的猜测,但是我 认为 这是正确的答案。您需要确保子查询正确关联:

SELECT deviceID,
       UserID,
       STUFF((SELECT ' | ' + sq.activityName + ' - ' + CONVERT(varchar(20),sq.createdDate, 0)
              FROM tbl_DailyLogMaster sq
              WHERE DLM.UserID = sq.UserId
                AND DLM.DeviceID = sq.DeviceID
                AND sq.createdDate >= CONVERT(date, GETDATE())
                AND sq.createdDate < DATEADD(DAY, 1, CONVERT(date, GETDATE()))
              ORDER BY CreatedDate
              FOR XML PATH(''),TYPE).value('.','varchar(MAX)'),1,3,'') AS tag --As yuou have no leading separator, no need for STUFF
FROM tbl_DailyLogMaster DLM
WHERE DLM.createdDate >= CONVERT(date, GETDATE())
  AND DLM.createdDate < DATEADD(DAY, 1, CONVERT(date, GETDATE()))
GROUP BY UserID,
         DeviceID;
2021-03-17