【问题标题】:TSQL Query to combine all records after first full record displayedTSQL 查询以在显示第一条完整记录后合并所有记录
【发布时间】:2018-05-22 12:54:37
【问题描述】:

大家好,这是我的问题。

我的查询输出如下所示(精简为几行):

|number |line |partNum |phoneNum     |qty_SN |qty_Property |qty_Name |qty_Time
------------------------------------------------------------------------------
|87     |1    |55G5    |555-789-7512 |00123  |Local        |Owner    |05:22
|87     |     |        |             |14988  |Local        |Seller   |10:44
|87     |     |        |             |521    |Remote       |Owner    |01:05
|87     |     |        |             |50697  |Local        |Seller   |11:41
|87     |     |        |             |2359   |Remote       |Seller   |04:45

而我想做的是:

|number |line |partNum |phoneNum     |qty_SN                     |qty_Property                    |qty_Name                         |qty_Time
------------------------------------------------------------------------------------------------------------------------------------------------------------------
|87     |1    |55G5    |555-789-7512 |00123,14988,521,50697,2359 |Local,Local,Remote,Local,Remote |Owner,Seller,Owner,Seller,Seller |05:22,10:44,01:05,11:41,04:45

请注意,所有 qty_ 列都合并到 第一个完整数据行中,而不是像第一个表中那样位于各自的行中。

第一个表的查询看起来像这样(再次被精简):

;WITH TheDATA AS (
   SELECT 
      BL.number                                  AS 'number', 
      BL.line                                    AS 'line', 
      BL.partNumber                              AS 'partNum',
      BL.phoneNumber                             AS 'phoneNum',
      L.qtySN                                    AS 'qty_SN',
      I.qtyProperty                              AS 'qty_Property',
      I.qtyName                                  AS 'qty_Name',
      I.qtyTime                                  AS 'qty_Time',
      ROW_NUMBER() Over (
         PARTITION BY 
             BL.number 
         ORDER BY
             BL.number
      )                                          AS 'RowNo'
   FROM
      BList                                      AS BL
   INNER JOIN Location                           AS L
      ON BL.ID                                    = L.Route
   INNER JOIN Inventory                          AS I
      ON L.ID                                     = I.prodID
   )
SELECT
   number                                        AS 'number',
   IIF(RowNo = 1, CONVERT(varchar, line), '')    AS 'line',
   IIF(RowNo = 1, partNumber, '')                AS 'partNum',
   IIF(RowNo = 1, phoneNumber, '')               AS 'phoneNum',
   qty_SN                                        AS 'qty_SN',
   qty_Property                                  AS 'qty_Property',
   qty_Name                                      AS 'qty_Name',
   qty_Time                                      AS 'qty_Time'
FROM
   TheData

【问题讨论】:

  • 您的TheDATA CTE 没有名为RowNo 的列,sql server 中也没有名为IFF() 的内置函数
  • @avb 已将 IFF 更正为 IIFAS 'RowNo'。感谢您了解这一点。
  • 您需要 4 个子查询,这些子查询使用有序 FOR XML 对具有 ROW_NUMBER 的集合进行正确排序。
  • @StealthRT 我看不出那个 AS 'RowNo' 是如何解决任何问题的。
  • 制表符半列,我的眼睛在流血!

标签: sql sql-server tsql sql-server-2016


【解决方案1】:

试试这个脚本

;WITH CTE(number ,line ,partNum ,phoneNum     ,qty_SN ,qty_Property ,qty_Name ,qty_Time)
AS
(
SELECT 87     ,1    ,  '55G5'    ,'555-789-7512'    ,00123  ,'Local'        ,'Owner'    ,'05:22' UNION ALL
SELECT 87     ,NULL    ,NULL       ,NULL        ,14988  ,'Local'        ,'Seller'   ,'10:44' UNION ALL
SELECT 87     ,NULL    ,NULL       ,NULL        ,521    ,'Remote'       ,'Owner'    ,'01:05' UNION ALL
SELECT 87     ,NULL    ,NULL       ,NULL        ,50697  ,'Local'        ,'Seller'   ,'11:41' UNION ALL
SELECT 87     ,NULL    ,NULL       ,NULL        ,2359   ,'Remote'       ,'Seller'   ,'04:45'
)
SELECT * FROM
(              
SELECT DISTINCT  number, line,partNum ,phoneNum,
        STUFF((SELECT ', '+CAST(qty_SN AS Varchar(10)) FROM CTE FOR XML PATH ('')),1,1,'') AS qty_SN,
        STUFF((SELECT ', '+CAST(qty_Property AS Varchar(10)) FROM CTE FOR XML PATH ('')),1,1,'') AS qty_Property,
        STUFF((SELECT ', '+CAST(qty_Name AS Varchar(10)) FROM CTE FOR XML PATH ('')),1,1,'') AS qty_Name,
        STUFF((SELECT ', '+CAST(qty_Time AS Varchar(10)) FROM CTE FOR XML PATH ('')),1,1,'') AS qty_Time
FROM CTE
)dt
WHERE line IS NOT NULL OR partNum IS  NOT NULL OR phoneNum IS NOT NULL

演示:http://rextester.com/IUA22801

【讨论】:

  • 感谢这个例子,Sreenu。使用本文中的一些东西指出了正确的答案!
  • @StealthRT 欢迎兄弟 :)
【解决方案2】:

最终结果查询如下所示:

;WITH CTE(number, line, partNum, phoneNum, qty_SN, qty_Property, qty_Name, qty_Time)
AS
(
    SELECT 87     ,1       ,'55G5'   ,'555-789-7512'  ,00123  ,'Local'  ,'Owner'  ,'05:22' UNION ALL
    SELECT 87     ,null    ,null     ,null            ,14988  ,'Local'  ,'Seller' ,'10:44' UNION ALL
    SELECT 87     ,null    ,null     ,null            ,521    ,'Remote' ,'Owner'  ,'01:05' UNION ALL
    SELECT 87     ,null    ,null     ,null            ,50697  ,'Local'  ,'Seller' ,'11:41' UNION ALL
    SELECT 87     ,null    ,null     ,null            ,2359   ,'Remote' ,'Seller' ,'04:45'
)
SELECT * FROM
(
  SELECT DISTINCT 
   number                                        AS 'number',
   line                                          AS 'line',
   partNum                                       AS 'partNum',
   phoneNum                                      AS 'phoneNum',
   qty_SN = (
      Stuff(
           (
             SELECT + ', ' + 
                CAST(qty_SN AS Varchar(100))  
             FROM 
                CTE 
             FOR 
                XML PATH ('')
           ), 1, 1, ''
      )
   ),
   qty_Property = (
      Stuff(
           (
             SELECT + ', ' + 
                CAST(qty_Property AS Varchar(100))  
             FROM 
                CTE 
             FOR 
                XML PATH ('')
           ), 1, 1, ''
      )
   ),
   qty_Name = (
      Stuff(
           (
             SELECT + ', ' + 
                CAST(qty_Name AS Varchar(100))  
             FROM 
                CTE 
             FOR 
                XML PATH ('')
           ), 1, 1, ''
      )
   ),
   qty_Time = (
      Stuff(
           (
             SELECT + ', ' + 
                CAST(qty_Time AS Varchar(100))  
             FROM 
                CTE 
             FOR 
                XML PATH ('')
           ), 1, 1, ''
      )
   )
  FROM
   CTE 
  WHERE 
    partNum IS NOT null
) AS dt

工作DEMO

【讨论】:

  • 一些注意事项,当您只有一组数据时,这将起作用,并且如果没有适当的 Order By 子句,则无法保证逗号分隔值的顺序。
  • @EzLo 是的,目前它返回 2 行,这比它返回的 6 行要好。仍在努力使其每个唯一编号仅返回 1 行
  • OP 已最后一次更新为最终工作示例。
猜你喜欢
  • 2011-09-11
  • 2019-11-01
  • 1970-01-01
  • 2012-03-26
  • 2023-03-28
  • 1970-01-01
  • 2017-05-08
  • 2013-06-14
  • 2020-06-11
相关资源
最近更新 更多