1

我有一个如下查询的表格,我每天在此表格中添加产品价格,并使用不同的卖家名称:

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 最低价
2012 年 1 月 16 日 AA 32 40 27 易趣
1/17/2012 BC 33.2 30 51.4 亚马逊
2012 年 1 月 18 日 DE 7.5 11.1 9.4 西尔斯
4

3 回答 3

3

我想这就是你要找的。

SQLFiddle

这有点难看,但这里有一个小故障。

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

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

(对不起,无法使该位对齐)。

我认为,如果您有一个可以做交叉表的报告工具,那么在那里做这件事会容易得多。

于 2013-11-07T17:32:01.037 回答
1

问题是这个要求:

我想要 n 个卖家的这样的结果

如果您的结果有固定的已知列数,则有多种技术可以透视您的数据。但是如果不知道列数,你就有麻烦了。SQL 语言确实希望您能够根据预先列的数量和类型来描述选择列表的结果集的确切性质。

听起来你不能这样做。这使您有两个选择:

  1. 查询数据以了解您拥有多少家商店及其名称,然后使用该信息构建动态 sql 语句。
  2. (首选选项)在客户端代码中执行数据透视。
于 2013-11-07T16:51:37.043 回答
0

这可能适用于 PIVOT。Microsoft 的文档实际上对 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 列,就像您包含日期和产品一样。

于 2013-11-07T16:44:21.420 回答