【问题标题】:SQL Combine Multiple rows into Multiple ColumnsSQL 将多行合并为多列
【发布时间】:2014-12-12 12:19:52
【问题描述】:

我一直在这里和整个网络上查看另一个示例,但我无法理解如何执行此操作。

我有一个网站,我将产品的每一条信息都拉到一个表格中以供查看,然后加载到 csv/excel 表格中。

它结合了 7 个表格并将它们吐出如下:(切断表格的其余部分以便于阅读)

ID  Filter     FilterValue  ParentItem  ItemTitle             
---------------------------------------------------------------
7   15         B            LE0001      LB PALETTE WHITE 127MM
7   16         Yes          LE0001      LB PALETTE WHITE 127MM  
7   18         Yes          LE0001      LB PALETTE WHITE 127MM
7   20         Std          LE0001      LB PALETTE WHITE 127MM
7   22         Yes          LE0001      LB PALETTE WHITE 127MM
7   23         Polyester    LE0001      LB PALETTE WHITE 127MM
7   25         White        LE0001      LB PALETTE WHITE 127MM
7   26         127mm        LE0001      LB PALETTE WHITE 127MM

使用此代码(当前显示的列是 tblprod.prodID、prodval.valueColumn、prodval.valueKey、tblprod.parentSKU 和 tblprod.prodTitle)

SELECT 
   tblprod.prodID as ID, prodval.valueColumn as Filter, 
   prodval.valueKey as FilterValue, tblprod.prodSKU as Item, 
   tblprod.parentSKU as ParentItem, tblprod.prodTitle as ItemTitle, 
   tblprod.prodConsumerTitle as ConsumerTitle, tblprod.itemGroup as ItemGroup, 
   tblprod.itemFamily as ItemFamily, tblprod.cutLengthCode as LengthCode, 
   tblprod.prodPackSize as PackSize, tblprod.prodMultQty as MultipleQuantity, 
   tblsu.ImportCode as SalesUnit, tblprod.prodPrice as SalesPrice , 
   tblprod.qtyDependent as QtyDep, tblprod.qtyTarget as Limit, 
   tblprod.targetPrice as Price, tblprod.prodLegacyImage as MainImage,
   catprod.IsPrimary as SafetyinMind, featlists.prodList as NEWLimited      
FROM 
   [Eclipse].[dbo].[tbl_Product] AS tblprod
LEFT JOIN 
   [Database].[dbo].[tbl_SalesUnit] AS tblsu ON tblsu.ID = tblprod.saleUnit
LEFT JOIN 
   [Database].[dbo].[tbl_ProductFilter] AS prodfil ON prodfil.ProdID = tblprod.prodID
LEFT JOIN 
   [Database].[dbo].[tbl_ProductFilterValues] AS prodval ON prodval.valueID = prodfil.valueID
LEFT JOIN
   [Database].[dbo].[tbl_ProductstoFeaturedLists] AS prodlists ON prodlists.prodID = tblprod.prodID
LEFT JOIN
   [Database].[dbo].[tbl_FeaturedLists] AS featlists ON featlists.ID = prodlists.listID
LEFT JOIN 
   [Database].[dbo].[tbl_CategoryProducts] AS catprod ON catprod.prodID = tblprod.prodID

重要的部分是我想组合相同 ID 的行,从过滤列 (prodval.valueColumn) 中创建列标题并用它们对应的值 (prodval.valueKey) 填充它们

我的问题是我不知道如何做到这一点,并且在阅读其他答案时我迷失了,其次有 19 个过滤器,并不是每个产品都会拥有所有这些(如您所见,上面的产品有 8 个)我不确定这样做是否会给我带来任何问题。过滤器的范围从 15 到 33,它们都被使用,但只是由不同的产品使用。

示例表如下所示。

ID  ParentItem  ItemTitle               Filter 15   Filter 16   Filter 17   Filter 18   Filter 19   Filter 20   Filter...
7   LE0001      LB PALETTE WHITE 127MM  B           YES                     YES                     Std 

如果有人可以提供任何帮助,我将不胜感激,但我无法理解它。

抱歉忘了提及我使用的是 SQL Server Management Studio

【问题讨论】:

  • 你用的是什么关系型数据库?
  • MSSQL - 服务器管理工​​作室。
  • select max(Filter),min(Filter) from yourtable 是什么?
  • 我不知道那是什么(抱歉没用)
  • Filter列的最小值和最大值是多少?

标签: sql sql-server multiple-columns multiple-tables


【解决方案1】:

尝试以下解决方案:

DECLARE @Columns VARCHAR(max)
;WITH cte
     AS (SELECT Min(Filter) minimum,
                Max(Filter) maximum
         FROM   yourtable)
SELECT @Columns = Stuff((SELECT ',' + '[ ' + CONVERT(VARCHAR(30), number, 121) + ']'
                         FROM   master..spt_values N
                         WHERE  EXISTS (SELECT 1
                                        FROM   cte
                                        WHERE  n.number BETWEEN cte.minimum AND cte.maximum)
                                AND type = 'P'
                         FOR XML PATH('')), 1, 1, '')

DECLARE @sql NVARCHAR(max)= 'select [ID],[ParentItem],[ItemTitle],' + @Columns + 
                            ' from (select [ID],[ParentItem],[ItemTitle],[Filter],[FilterValue] from yourtable) t 
                            pivot
                            (MAx(FilterValue)
                            FOR Filter in(' + @Columns + ')
                            )as pvt'

EXEC sp_executesql
  @sql 

sqlfiddle

【讨论】:

  • 成功了,谢谢。我不太明白为什么,但我只需要花时间去研究它。非常感谢。
  • 称为动态枢轴。首先,我创建了您需要的其他列的列表并将其存储在@columns 中,然后我从子查询查询select [ID],[ParentItem],[ItemTitle],[Filter],[FilterValue] from yourtable 中选择了固定列和动态列。动态列的值由pivot 块填充。
  • 啊,这很有意义。非常感谢。
【解决方案2】:

使用 PIVOT 获取结果。 Fiddler Demo

CREATE TABLE #Sample
(
    ID INT,  
    Filter INT,    
    FilterValue VARCHAR(100),  
    ParentItem VARCHAR(100),  
    ItemTitle VARCHAR(100)
)

INSERT INTO #Sample VALUES(7,   15,'B',   'LE0001','LB PALETTE WHITE 127MM')
INSERT INTO #Sample VALUES(7,   16,'Yes', 'LE0001','LB PALETTE WHITE 127MM')  
INSERT INTO #Sample VALUES(7,   18,'Yes', 'LE0001','LB PALETTE WHITE 127MM')
INSERT INTO #Sample VALUES(7,   20,'Std', 'LE0001','LB PALETTE WHITE 127MM')
INSERT INTO #Sample VALUES(7,   22,'Yes', 'LE0001','LB PALETTE WHITE 127MM')
INSERT INTO #Sample VALUES(7,   23,'Polyester',    'LE0001','LB PALETTE WHITE 127MM')
INSERT INTO #Sample VALUES(7,   25,'White','LE0001','LB PALETTE WHITE 127MM')
INSERT INTO #Sample VALUES(7,   26,'127mm','LE0001','LB PALETTE WHITE 127MM')


SELECT P.ID,P.ParentItem, P.ItemTitle, 
 Min(Filter15) Filter15,
 Min(Filter16) Filter16 ,
 Min(Filter17)Filter17,
 Min(Filter18)Filter18,
 Min(Filter19)Filter19,
 Min(Filter20)Filter20,
 Min(Filter21)Filter21,
 Min(Filter22)Filter22,
Min(Filter23)Filter23,
Min(Filter24)Filter24,
Min(Filter25)Filter25,
Min(Filter26)Filter26,
Min(Filter27)Filter27,
Min(Filter28)Filter28,
Min(Filter29)Filter29,
Min(Filter30)Filter30,
Min(Filter31)Filter31,
Min(Filter32)Filter32,
Min(Filter33)Filter33
FROM 
 (SELECT *,
               'Filter' + CONVERT(VARCHAR(30), Filter)  AS Filter_A

        FROM   #Sample
 ) AS A

 PIVOT (Min(A.FilterValue) FOR Filter_A in 
      (Filter15,Filter16,Filter17,Filter18,Filter19,
       Filter20,Filter21,Filter22,Filter23,Filter24,
       Filter25,Filter26,Filter27,Filter28,Filter29,
       Filter30,Filter31,Filter32,Filter33)) AS P
GROUP BY P.ID,P.ParentItem, P.ItemTitle 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-05-27
    • 2020-06-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-07
    • 2011-12-21
    • 1970-01-01
    相关资源
    最近更新 更多