如何连接固定限制为2的列值并在SQL中对列进行分组?

mf98qq94  于 2022-10-22  发布在  其他
关注(0)|答案(2)|浏览(182)

我有一张table作为图像。

TableName    ColumnName     RecordId    Caption          ImageType      ROTId     DetailRecordId
Table2      PAUTDPhoto_bin  1462        test            PAUTPhotos      1041383   11480170
Table2      PAUTDPhoto_bin  1463        test1           PAUTPhotos      1041383   11480170
Table2      PAUTDPhoto_bin  1464        testing photo   PAUTPhotos      1041383   11480170
Table1      ItemPhoto_bin   11480170    caption          ItemPhoto      1041383   11480170
Table1      ItemPhoto_bin   11480171    test photo       ItemPhoto      1041383   11480171
Table1      ItemPhoto_bin   11480172    description      ItemPhoto      1041383   11480172
Table2      PAUTDPhoto_bin  1465        test             PAUTPhotos     1041383   11480172
Table2      PAUTDPhoto_bin  1466        55               PAUTPhotos     1041383   11480172

我的输出选择查询将执行以下操作,
1.)需要按DetailRecordId和ColumnName进行GroupBy。
2.)在GroupBy之后,我想合并RecordId和Caption列。只需将2个值合并为一个值。
我的输出应该是,

TableName    ColumnName     RecordId    Caption          ImageType      ROTId     DetailRecordId
Table2      PAUTDPhoto_bin  1462$1463   test$test1       PAUTPhotos     1041383   11480170
Table2      PAUTDPhoto_bin  1464        testing photo    PAUTPhotos     1041383   11480170
Table1      ItemPhoto_bin   11480170    caption          ItemPhoto      1041383   11480170
Table1      ItemPhoto_bin   11480171    test photo       ItemPhoto      1041383   11480171
Table1      ItemPhoto_bin   11480172    description      ItemPhoto      1041383   11480172
Table2      PAUTDPhoto_bin  1465$1466   test$55          PAUTPhotos     1041383   11480172

**注:**我想将RecordId和Caption列与其中只有2个值的列连接起来。

1l5u6lss

1l5u6lss1#

我们可以使用LEAD为任何给定的DetailRecordId+ColumnName对拉取下一行,并使用模(%)仅抓取第一、第三、第五行,以此类推。

WITH cte AS
(
  SELECT 
    TableName,
    ColumnName,
    RecordId,
    ImageType,
    ROTId,
    DetailRecordId, 
    NewRecordId = CONCAT(RTRIM(RecordId), '$' 
       + LEAD(RecordId,1) OVER (PARTITION BY DetailRecordId, ColumnName 
         ORDER BY ColumnName)),
    NewCaption = CONCAT(RTRIM(Caption), '$' 
       + LEAD(Caption,1) OVER (PARTITION BY DetailRecordId, ColumnName 
         ORDER BY ColumnName)),
    rn = ROW_NUMBER() OVER (PARTITION BY DetailRecordId, ColumnName 
         ORDER BY ColumnName)
  FROM dbo.YourTableName
)
SELECT 
  TableName,
  ColumnName,
  RecordId = NewRecordId,
  Caption = NewCaption,
  ImageType,
  ROTId,
  DetailRecordId
FROM cte 
WHERE rn % 2 = 1;

工作示例in this fiddle
重复的OVER()子句有点让我烦恼;在SQL Server 2022中,我们将能够通过新的“sharable”WINDOW子句大大简化这一过程:

WITH cte AS
(
  SELECT 
    TableName,
    ColumnName,
    RecordId,
    ImageType,
    ROTId,
    DetailRecordId, 
    NewRecordId = CONCAT(RTRIM(RecordId), '$' + LEAD(RecordId,1) OVER W),
    NewCaption  = CONCAT(RTRIM(Caption),  '$' + LEAD(Caption,1) OVER W),
    rn = ROW_NUMBER() OVER W
  FROM dbo.YourTableName
  -- magic vvv
  WINDOW W AS ( PARTITION BY DetailRecordId, ColumnName ORDER BY ColumnName) 
  -- magic ^^^
)
SELECT 
  TableName,
  ColumnName,
  RecordId = NewRecordId,
  Caption = NewCaption,
  ImageType,
  ROTId,
  DetailRecordId
FROM cte 
WHERE rn % 2 = 1;
gajydyqb

gajydyqb2#

如果您的SQL版本支持STRING_AGG函数,可以尝试以下操作:

SELECT MAX(TableName) TableName, ColumnName,STRING_AGG(D.RecordId, '$') RecordId,
       STRING_AGG(D.Caption, '$') Caption, MAX(ImageType) ImageType, 
       MAX(ROTId) ROTId, MAX(DetailRecordId) DetailRecordId
FROM
(
  SELECT *,
         (COUNT(*) OVER (PARTITION BY ColumnName, DetailRecordId ORDER BY RecordId) + 1) /2  grp
  FROM table_name
) D
GROUP BY ColumnName, DetailRecordId, D.grp
ORDER BY  DetailRecordId, ColumnName

对于其他版本:

WITH CTE AS
  (
   SELECT *,
         (COUNT(*) OVER (PARTITION BY ColumnName, DetailRecordId ORDER BY RecordId) + 1) /2  grp
   FROM table_name
  )

SELECT MAX(TableName) TableName, ColumnName,
       STUFF((SELECT '$' + CAST(T.RecordId as VARCHAR(MAX))
              FROM CTE T WHERE T.ColumnName = D.ColumnName AND
                               T.DetailRecordId = D.DetailRecordId AND
                               T.grp = D.grp 
              FOR xml PATH ('')), 1, 1, '') RecordId,
       STUFF((SELECT '$' + CAST(T.Caption as VARCHAR(MAX))
              FROM CTE T WHERE T.ColumnName = D.ColumnName AND
                               T.DetailRecordId = D.DetailRecordId AND
                               T.grp = D.grp 
              FOR xml PATH ('')), 1, 1, '') Caption,
       MAX(ImageType) ImageType, MAX(ROTId) ROTId, MAX(DetailRecordId) DetailRecordId
FROM CTE D
GROUP BY ColumnName, DetailRecordId, D.grp
ORDER BY  DetailRecordId, ColumnName

请参阅demo

相关问题