SQL中没有固定列数的列的串联

时间:2019-01-02 04:13:42

标签: sql sql-server

我正在尝试连接SQL中的一堆列。

问题在于没有固定的列数,因此可能必须在一次运行中将18列连接在一起,而在下一次运行中将30列连接在一起。

表结构如下:

concatbase

ID  | planprefix | plannumber | ConcatField_1 | ConcatField_2 | ConcatField_3 | ....
----+------------+------------+---------------+---------------+---------------+ ....
1   |   p        | 11         | 100-150       | 300           | 302           | ....
1   |   P        | 111        | 101           | NULL          | NULL          | ....
1   |   P        | 2222       | 600-908       | 1010          | NULL          | ....
4   |   D        | 33333      | 400-406       | NULL          | NULL          | ....
5   |   D        | 444444     | 300           | NULL          | NULL          | ....
6   |   p        | 19         | 200           | 300-308       | 400           | ....

RPD_STAGING (给出ID 1示例数据的预期结果)

Rank    | ID        | semi_rp                   |
--------+-----------+---------------------------+
1       |   1       | 100-150 & 300 & 302 P11   |
2       |   1       | 101 P11                   |
3       |   1       | 608-908 & 1010 P2222      |

我正在使用以下SQL语句将其连接在一起:

SELECT DISTINCT 
    DENSE_RANK() OVER (PARTITION BY propertyid ORDER BY plannumber) AS rank,
    propertyid,
    CASE WHEN ConcatField_1 IS NULL THEN ' ' + planprefix + plannumber ELSE ConcatField_1 END +
    CASE WHEN ConcatField_2  IS NULL AND ConcatField_1  IS NOT NULL THEN ' ' + planprefix + plannumber when ConcatField_2  is null and ConcatField_1  IS NULL then  '' ELSE ' & ' + ConcatField_2 END + 
    CASE WHEN ConcatField_3  IS NULL AND ConcatField_2  IS NOT NULL THEN ' ' + planprefix + plannumber when ConcatField_3  is null and ConcatField_2  IS NULL then '' ELSE ' & ' + ConcatField_3 END +  
    CASE WHEN ConcatField_4  IS NULL AND ConcatField_3  IS NOT NULL THEN ' ' +  planprefix + plannumber when ConcatField_4  is null and ConcatField_3  IS NULL then '' ELSE ' & ' + ConcatField_4 END + 
    CASE WHEN ConcatField_5  IS NULL AND ConcatField_4  IS NOT NULL THEN ' ' + planprefix + plannumber when ConcatField_5  is null and ConcatField_4  IS NULL then '' ELSE ' & ' + ConcatField_5 END + 
    CASE WHEN ConcatField_6  IS NULL AND ConcatField_5  IS NOT NULL THEN ' ' + planprefix + plannumber when ConcatField_6  is null and ConcatField_5  IS NULL then '' ELSE ' & ' + ConcatField_6 END + 
    CASE WHEN ConcatField_7  IS NULL AND ConcatField_6  IS NOT NULL THEN ' ' + planprefix + plannumber when ConcatField_7  is null and ConcatField_6  IS NULL then '' ELSE ' & ' + ConcatField_7 END + 
    CASE WHEN ConcatField_8  IS NULL AND ConcatField_7  IS NOT NULL THEN ' ' + planprefix + plannumber when ConcatField_8  is null and ConcatField_7  IS NULL then '' ELSE ' & ' + ConcatField_8 END + 
    CASE WHEN ConcatField_9  IS NULL AND ConcatField_8  IS NOT NULL THEN ' ' + planprefix + plannumber when ConcatField_9  is null and ConcatField_8  IS NULL then '' ELSE ' & ' + ConcatField_9 END + 
    CASE WHEN ConcatField_10 IS NULL AND ConcatField_9  IS NOT NULL THEN ' ' + planprefix + plannumber when ConcatField_10 is null and ConcatField_9  IS NULL then '' ELSE ' & ' + ConcatField_10 END + 
    CASE WHEN ConcatField_11 IS NULL AND ConcatField_10 IS NOT NULL THEN ' ' + planprefix + plannumber when ConcatField_11 is null and ConcatField_10 IS NULL then '' ELSE ' & ' + ConcatField_11 END + 
    CASE WHEN ConcatField_12 IS NULL AND ConcatField_11 IS NOT NULL THEN ' ' + planprefix + plannumber when ConcatField_12 is null and ConcatField_11 IS NULL then '' ELSE ' & ' + ConcatField_12 END + 
    CASE WHEN ConcatField_13 IS NULL AND ConcatField_12 IS NOT NULL THEN ' ' + planprefix + plannumber when ConcatField_13 is null and ConcatField_12 IS NULL then '' ELSE ' & ' + ConcatField_13 END + 
    CASE WHEN ConcatField_14 IS NULL AND ConcatField_13 IS NOT NULL THEN ' ' + planprefix + plannumber when ConcatField_14 is null and ConcatField_13 IS NULL then '' ELSE ' & ' + ConcatField_14 END + 
    CASE WHEN ConcatField_15 IS NULL AND ConcatField_14 IS NOT NULL THEN ' ' + planprefix + plannumber when ConcatField_15 is null and ConcatField_14 IS NULL then '' ELSE ' & ' + ConcatField_15 END + 
    CASE WHEN ConcatField_16 IS NULL AND ConcatField_15 IS NOT NULL THEN ' ' + planprefix + plannumber when ConcatField_16 is null and ConcatField_15 IS NULL then  '' ELSE ' & ' + ConcatField_16 END + 
    CASE WHEN ConcatField_17 IS NULL AND ConcatField_16 IS NOT NULL THEN ' ' + planprefix + plannumber when ConcatField_17 is null and ConcatField_16 IS NULL then '' ELSE ' & ' + ConcatField_17 END + 
    CASE WHEN ConcatField_18 IS NULL AND ConcatField_17 IS NOT NULL THEN ' ' + planprefix + plannumber when ConcatField_18 is null and ConcatField_17 IS NULL then '' ELSE ' & ' + ConcatField_18 END AS semi_rpd  
INTO 
    #RPD_STAGING
FROM
    #concat_base

有人可以协助我创建一个可以处理任意数量的ConcatFields的解决方案吗?

如果可能的话,我想坚持使用SQL,但是如果有必要,我可以使用其他工具。如果您需要进一步的信息,请告诉我。

3 个答案:

答案 0 :(得分:0)

我认为使用CONCAT()内置SQL函数比Case更好,因为它可以处理空值。例如,您可以使用

SELECT 
  DISTINCT DENSE_RANK() OVER(
    PARTITION BY propertyid 
    ORDER BY 
      plannumber
  ) AS rank, 
  propertyid, 
  CONCAT(
    planprefix, plannumber, ConcatField_1, 
    ConcatField_2...
  ) INTO #RPD_STAGING
FROM 
  #concat_base

答案 1 :(得分:0)

此代码应该允许在未知数量的以“ ConcatField_”开头的列上进行连接我无法纠正/调试代码(我没有运行SQL Server),但是所有元素假设它们都以ConcatField开头,则此处允许跨未知数量的字段进行动态串联。

SELECT 
  DISTINCT DENSE_RANK() OVER(
    PARTITION BY propertyid 
    ORDER BY 
      plannumber
  ) AS rank, P,
  propertyid, 

  ) INTO #RPD_STAGING
FROM 
  #concat_base,
CROSS APPLY (SELECT CONCAT(', ' , col.Name)
   FROM INFORMATION_SCHEMA.COLUMNS AS col            
   WHERE col like 'ConcatField*'
   FOR XML PATH('') ) AS P (Concat_list) 

答案 2 :(得分:0)

感谢所有建议,我最终重写了整个内容。

我没有像生成无限数量的列那样执行以下操作!

DROP TABLE IF EXISTS #temp,#temp2

CREATE TABLE #temp
(
ID INT
,Parcel int
,lot NVARCHAR(255)
);

INSERT INTO #temp(ID, Parcel, lot)
VALUES
 (1,111 ,1 ),(1,111 ,2 ),(1,111 ,3 ),(2,1212,1 ),(2,1212,3 ),(2,1212,4 ),(3,1333,1 ),(3,1333,7 ),(4,5555,1 ),(4,5555,7 )
,(4,5544,1 ),(4,5544,2 ),(5,1809,1 ),(5,1809,2 ),(5,1809,3 ),(5,1809,5 ),(5,1810,6 ),(5,1810,7 ),(5,1810,8 )

SELECT ID,Parcel,
(SELECT lot + ',' 
FROM #temp p2
WHERE p1.ID = p2.ID
AND p1.Parcel = p2.Parcel
ORDER BY ID,Parcel
    FOR XML PATH ('')) AS Products
    INTO #temp2 FROM #temp p1 
GROUP BY p1.ID,p1.Parcel

SELECT * FROM #temp2