在同一个表中合并多个行

时间:2014-08-15 01:19:52

标签: sql sql-server

我不太确定这是否可以通过单独的SQL查询实现。

我们说我有一张包含以下数据和结构的表格:

ID  |  Item Code  |   Store Name  |  Store Price
1   |     101     |      Red      |    10.00
2   |     101     |      Blue     |     9.75
3   |     102     |      Green    |    11.50
4   |     103     |      Black    |     5.75
5   |     103     |      Yellow   |     4.50
6   |     103     |      Purple   |     6.00

我希望得到这样的结果:

ItemCode | Store1Name | Store1Price | Store2Name | Store2Price | Store3Name | Store3Price
  101    |    Red     |   10.00     |    Blue    |    9.75     |            |
  102    |    Green   |   11.50     |            |             |            | 
  103    |    Purple  |    6.00     |    Black   |    5.75     |   Yellow   |    4.50

我目前正在尝试使用JOINS来解决此问题,但仍然无法获得所需的结果。

我创建的JOIN示例:

SELECT A.ItemCode [ItemCode], A.StoreName [Store1Name], A.StorePrice [Store1Price],
       B.StoreName [Store2Name], B.StorePrice [Store2Price],
       C.StoreName [Store3Name], c.StorePrice [Store3Price]
FROM   tblStorePrice A
         LEFT JOIN tblStorePrice B ON A.ItemCode = B.ItemCode AND A.ID <> B.ID
         LEFT JOIN tblStorePrice C ON A.ItemCode = C.ItemCode AND A.ID <> C.ID

注意:

该表仅为每个商品代码存储三个商店(最多)。少于3个商店的商品代码应该具有结果的空值。

希望得到积极的反馈和回应。先谢谢你们! :)

3 个答案:

答案 0 :(得分:2)

家伙!感谢您的时间和精力。正如我之前所说的那样,我使用JOIN来提出这个解决方案。但是,我知道这不是目前为止最好的解决方案,但我会在此期间使用它。

使用SELF JOIN:

SELECT A.ItemCode [ItemCode], A.StoreName [Store1Name], A.StorePrice [Store1Price],B.StoreName [Store2Name], B.StorePrice [Store2Price],C.StoreName [Store3Name], C.StorePrice [Store3Price] FROM tblStorePrice A LEFT JOIN tblStorePrice B ON A.ItemCode = B.ItemCode AND A.ID <> B.ID LEFT JOIN tblStorePrice C ON B.ItemCode = C.ItemCode AND B.ID <> C.ID AND A.ID <> C.ID

这将得到如下结果:enter image description here

它仍然不是所需的输出,但将此结果插入另一个表(使用主键)并选择不同的项目代码就可以了。

答案 1 :(得分:1)

试试此代码

表格创建

CREATE TABLE [dbo].[StorePrices](
    [ID] [int] IDENTITY(1,1) NOT NULL,
    [ItemCode] [int] NULL,
    [StoreName] [varchar](256) NULL,
    [StorePrice] [float] NULL,
 CONSTRAINT [PK_StorePrices] PRIMARY KEY CLUSTERED 
(
    [ID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

然后是SQL的价格

Select 
    DistinctItems.ItemCode,
    StoreRedPrices.StorePrice 'Red',
    StoreBluePrices.StorePrice 'Blue',
    StoreYellowPrices.StorePrice 'Yellow'
from (select distinct ItemCode from storeprices) DistinctItems
left join storeprices StoreRedPrices on StoreRedPrices.ItemCode = DistinctItems.ItemCode and StoreRedPrices.StoreName = 'Red'
left join storeprices StoreBluePrices on StoreBluePrices.ItemCode = DistinctItems.ItemCode and StoreBluePrices.StoreName = 'Blue'
left join storeprices StoreYellowPrices on StoreYellowPrices.ItemCode = DistinctItems.ItemCode and StoreYellowPrices.StoreName = 'Yellow'

编辑:我现在知道商店是动态的XML替代品

select 
    ItemCode,
    (select StoreName, StorePrice from StorePrices StorePrice where ItemCode = Item.ItemCode for xml auto,type) StorePrices
from StorePrices Item
group by Item.ItemCode
for xml auto, root('Items')

我希望这对你有所帮助吗?如果没有,那么您可能需要查看数据透视查询

此致

利安

答案 2 :(得分:1)

使用PIVOT或CTE可能更容易解决但我决定使用光标

架构:

CREATE TABLE tblStorePrice (
  ID INTEGER,
  ItemCode INTEGER,
  StoreName VARCHAR(10),
  StorePrice DECIMAL(10,2)
);

INSERT INTO tblStorePrice VALUES (1,101,'Red',10.00)
                                ,(2,101,'Blue',9.75)
                                ,(3,102,'Green',11.50)
                                ,(4,103,'Black',5.75)
                                ,(5,103,'Yellow',4.5)
                                ,(6,103,'Purple',6.00)

代码:

CREATE TABLE #StoreMatrix (
  ItemCode INTEGER,
  Store1Name Varchar(10),
  Store1Price DECIMAL(10,2),
  Store2Name Varchar(10),
  Store2Price DECIMAL(10,2),
  Store3Name Varchar(10),
  Store3Price DECIMAL(10,2),
)

DECLARE @ItemCode INTEGER,
        @Store1Name Varchar(10),
        @Store1Price DECIMAL(10,2),
        @Store2Name Varchar(10),
        @Store2Price DECIMAL(10,2),
        @Store3Name Varchar(10),
        @Store3Price DECIMAL(10,2)

DECLARE cStoreMatrix Cursor FOR
  SELECT DISTINCT ItemCode
  FROM tblStorePrice

OPEN cStoreMatrix

FETCH NEXT FROM cStoreMAtrix INTO @ItemCode

WHILE @@FETCH_STATUS = 0
BEGIN

  SELECT TOP 1 @Store1Name = StoreName, @Store1Price = StorePrice
  FROM tblStorePrice
  WHERE ItemCode = @ItemCode
  ORDER BY StoreName

SQL 2008:

  ;WITH T AS(
    SELECT ROW_NUMBER() OVER(ORDER BY StoreName) AS row, *
    FROM tblStorePrice
    WHERE ItemCode = @ItemCode)
  SELECT @Store2Name = ISNULL(StoreName,'')
        ,@Store2Price = ISNULL(StorePrice,0) FROM T
  WHERE row IN (2)

  ;WITH T AS(
    SELECT ROW_NUMBER() OVER(ORDER BY StoreName) AS row, *
    FROM tblStorePrice
    WHERE ItemCode = @ItemCode)
  SELECT @Store3Name = ISNULL(StoreName,'')
        ,@Store3Price = ISNULL(StorePrice,0) FROM T
  WHERE row IN (3)

SQL 2012:

  SELECT @Store2Name = ISNULL(StoreName,'')
        ,@Store2Price = ISNULL(StorePrice,0)
  FROM tblStorePrice
  WHERE ItemCode = @ItemCode
  ORDER BY StoreName
  Offset 1 Rows 
  Fetch Next 1 Rows Only

  SELECT @Store3Name = ISNULL(StoreName,'')
        ,@Store3Price = ISNULL(StorePrice,0)
  FROM tblStorePrice
  WHERE ItemCode = @ItemCode
  ORDER BY StoreName
  Offset 2 Rows 
  Fetch Next 1 Rows Only

代码:

  INSERT INTO #storeMatrix( ItemCode
                           ,Store1Name
                           ,Store1Price
                           ,Store2Name
                           ,Store2Price
                           ,Store3Name
                           ,Store3Price)
  VALUES( @ItemCode
         ,@Store1Name
         ,@Store1Price
         ,@Store2Name
         ,@Store2Price
         ,@Store3Name
         ,@Store3Price)

  SELECT @Store1Name = NULL
        ,@Store1Price = NULL
        ,@Store2Name = NULL
        ,@Store2Price = NULL
        ,@Store3Name = NULL
        ,@Store3Price = NULL


FETCH NEXT FROM cStoreMAtrix INTO @ItemCode
END
CLOSE cStoreMatrix
DEALLOCATE CStoreMatrix

SELECT * FROM #StoreMatrix