用 SQL 替代 STRING_AGG

Alternative to STRING_AGG in with SQL

我有一个table如下

| 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 时,它是准确的并且 return 是我想要的结果

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;

会return这样

| 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;

它return是这样的

| 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      |

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

有点瞎猜,但我认为这是正确答案。您需要确保子查询正确关联:

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;