我有一张表,目前有很长的设备列表和有关何时售出的信息。我需要拿一张看起来像这样的表:
Item | Time Sold
--------------------
A 05/2010
B 04/2010
C 03/2010
A 04/2010
A 05/2010
然后有一个表格,该项目作为第一列,日期的计数为列标题,如下所示:
Item | Count_03/2010 | Count_04/2010 | Count_05/2010
-------------------------------------------------------------
A | 0 | 1 | 2
B | 0 | 1 | 0
C | 1 | 0 | 0
有一种简单的方法吗?我知道在其他语言中有一个命令可以执行它,想知道SQL是否有一个。
我的问题是有多个表,在某些表中,月份可能与其他表格不同。无论如何编写一个将适用于它们的脚本,通过获取列出的变量然后使用它们来创建代码中的列?如果我知道月份总是相同的话,我可以写一个,但由于它们是可变的,有没有办法做到这一点。
答案 0 :(得分:4)
SQL Server 2005及更高版本有一个名为pivot
的东西,但它仍然不是一个命令,你需要知道Time sold列中的值。你可以使用Itzik Ben-Gan在他的Inside Microsoft SQL Server 2008: T-SQL Querying书中所展示的动态透视方法
实施例
create table #test (Item char(1), TimeSold varchar(20))
insert #test values('A','05/2010')
insert #test values('B','04/2010')
insert #test values('C','03/2010')
insert #test values('A','04/2010')
insert #test values('A','05/2010')
SELECT *
FROM
(SELECT Item,TimeSold
FROM #test) AS pivTemp
PIVOT
( COUNT(TimeSold)
FOR TimeSold IN ([05/2010],[04/2010],[03/2010])
) AS pivTable
答案 1 :(得分:3)
我没有测试过,但以下情况应该有效。我使用子查询来获得所需的结果:
select item,
(select count(*) from items i where time_sold between '02/2010' AND '03/2010' i.item=item ),
(select count(*) from items i where time_sold between '03/2010' AND '04/2010' i.item=item ),
(select count(*) from items i where time_sold between '04/2010' AND '05/2010' i.item=item )
from items;
答案 2 :(得分:2)
本机MS-SQL不提供任何以您想要的表格格式显示数据的功能,而不知道您要从中生成列名的值。
有一个great article on dynamically creating crosstab queries in MS-SQL。这是一个黑客,但看起来它应该工作。
否则采取更灵活的方法......
Select Distinct
Item,
Time Sold,
Count([Item])
From
MyTable
Group By
Item,
Time Sold
这会给你:
Item | Time Sold | Count ------------------------ A | 05/2010 | 2 A | 04/2010 | 1 B | 04/2010 | 1 C | 03/2010 | 1
这是一种更适合数据分析的格式,因为您可以编写查询来处理数据,因为列名已知。
例如,您可以在报告工具中使用此数据:
要使其符合您所要求的报告格式,您最好使用Crystal Reports或Excel等报告工具。
Excel和Crystal Report都支持数据透视表,用于以您请求的表格格式显示数据(而且它看起来也会更好!)。
答案 3 :(得分:1)
您可以group by
获取每个项目的汇总结果。使用sum
和case
,您可以计算特定时期内的商品数量。例如:
select item
, sum(case when time_sold between '02/2010' and '03/2010' then 1 end)
, sum(case when time_sold between '03/2010' and '04/2010' then 1 end)
, sum(case when time_sold between '04/2010' and '05/2010' then 1 end)
from items
group by
item
如果您有多种格式的源表,请在子查询中将它们合并在一起。我将此示例限制为仅一个范围以节省空间:
select item
, sum(IsInRange1)
from (
select item
, case when time_sold between '01/2010' and '03/2010'
then 1 end as IsInRange1
from usa_items
union all
select item
, case when time_sold in ('gennaio', 'febbraio', 'marzo')
then 1 end
from italian_items
union all
select item
, case when time_sold between '2010-01-01' and '2010-03-01'
then 1 end
from iso_items
) SubqueryAlias
group by
item