sql中的产品价格比较

时间:2013-11-07 16:16:38

标签: sql sql-server sql-server-2008 tsql

我有一个表格看起来像下面给出的查询,我每天在这个表格中添加产品价格,与不同的卖家名称:

create table Product_Price
    (
      id int,
      dt date,
      SellerName varchar(20),
      Product varchar(10),
      Price money
    )

    insert into Product_Price values (1, '2012-01-16','Sears','AA', 32)
    insert into Product_Price values (2, '2012-01-16','Amazon', 'AA', 40)
    insert into Product_Price values (3, '2012-01-16','eBay','AA', 27)

    insert into Product_Price values (4, '2012-01-17','Sears','BC', 33.2)
    insert into Product_Price values (5, '2012-01-17','Amazon', 'BC',30)
    insert into Product_Price values (6, '2012-01-17','eBay', 'BC',51.4)

    insert into Product_Price values (7, '2012-01-18','Sears','DE', 13.5)
    insert into Product_Price values (8, '2012-01-18','Amazon','DE', 11.1)
    insert into Product_Price values (9, '2012-01-18', 'eBay','DE', 9.4)

我想要这样的结果给n个卖家(因为更多的卖家在表中添加)

DT           PRODUCT   Sears[My Site]   Amazon   Ebay   Lowest Price
1/16/2012    AA        32               40       27     Ebay
1/17/2012    BC        33.2             30       51.4   Amazon
1/18/2012    DE        7.5              11.1     9.4    Sears

3 个答案:

答案 0 :(得分:3)

我认为这就是你要找的东西。

SQLFiddle

这有点难看,但这里有点故障。

此块允许您获取值的动态列表。 (不记得我从谁那里偷了这个,但它太棒了。没有这个,枢轴真的不比一个巨大的案例陈述方法更好。)

DECLARE @cols AS VARCHAR(MAX)
DECLARE @query AS NVARCHAR(MAX)
select @cols = STUFF((SELECT distinct ',' +
                        QUOTENAME(SellerName)
                      FROM Product_Price
                      FOR XML PATH(''), TYPE
                     ).value('.', 'NVARCHAR(MAX)') 
                        , 1, 1, '')

你的@cols变量如下:

[Amazon],[eBay],[Sears]

然后你需要构建一个整个查询的字符串:

select @query = 
'select piv1.*, tt.sellername from (
select *
from
(select dt, product, SellerName,  sum(price) as price from product_price group by  dt, product, SellerName) t1

pivot (sum(price) for SellerName in (' + @cols + '))as bob
) piv1
inner join
(select t2.dt,t2.sellername,t1.min_price from
(select dt,  min(price) as min_price  from product_price group by  dt) t1
inner join (select dt,sellername, sum(price) as price from product_price group by dt,sellername) t2 on t1.min_price = t2.price) tt
on piv1.dt = tt.dt
'

piv1派生表为您提供了旋转值。巧妙命名的tt派生表可以让您获得每天销售额最低的卖家。 (告诉你它有点难看。)

最后,您运行查询:

execute(@query)

你得到:

 DT     PRODUCT     AMAZON  EBAY    SEARS   SELLERNAME
2012-01-16  AA  40  27  32  eBay
2012-01-17  BC  30  51.4    33.2    Amazon
2012-01-18  DE  11.1    9.4     13.5    eBay

(抱歉,不能让那个位排队)。

我认为如果你有一个可以做交叉表的报告工具,那么这将更容易做到。

答案 1 :(得分:1)

问题在于这个要求:

  

我想要n个卖家的结果

如果您的结果具有固定的已知列数,则可以使用多种方法PIVOT数据。但如果列数不知道,那你就麻烦了。 SQL语言真的希望您能够根据前面列的数量和类型来描述选择列表的结果集的确切性质。

听起来你不能这样做。这为您提供了两个选项:

  1. 查询数据以了解您拥有的商店数量及其名称,然后使用该信息构建动态sql语句。
  2. (首选项)在客户端代码中执行数据透视。

答案 2 :(得分:0)

这可能适用于PIVOT。微软的文档实际上对PIVOT和UNPIVOT非常有用。

http://technet.microsoft.com/en-us/library/ms177410(v=sql.105).aspx

基本上,它允许您选择一个列,在您的情况下为SellerName,并将其转出,以便列的元素本身成为新结果中的列。新“Ebay”,“Amazon”等列中的值将是您选择的聚合 - 在这种情况下是价格的MAX或MIN或AVG。

对于最终的“最低价格”列,您可能最好通过在主查询中执行子查询来获得最佳服务,该子查询找到每个产品/日期的最低值,然后将其重新加入以获取SellerName。类似的东西:

SELECT 
    Product_Price.Date
    ,Product_Price.Product
    ,Product_Price.MinimumSellerName
FROM
(SELECT 
MIN(Price) AS min_price
,Product
,Date
FROM Product_Price
GROUP BY
Product
,Date) min_price
INNER JOIN Product_Price
ON min_price.Product = Product_Price.Product
    AND min_price.Date = Product_Price.Date

然后只需将枢轴放在那个并包含MinimumSellerName列,就像包含日期和产品一样。