2

我有一张表,目前是一长串设备和有关它们何时出售的信息。我需要拿一张看起来像这样的桌子:

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 是否有一个。

编辑

我的问题是有不止一张表,并且在某些表中的月份可能与其他表中的不同。无论如何,通过获取列出的变量然后使用这些变量在代码中创建列来编写一个适用于它们的脚本吗?如果我知道月份总是相同的,我可以写一个,但由于它们是可变的,有没有办法做到这一点。

4

4 回答 4

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
于 2010-08-18T13:15:37.810 回答
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;
于 2010-08-18T13:09:03.860 回答
2

在不知道要从中生成列名称的值的情况下,本机 MS-SQL 不提供任何功能来以所需的表格格式显示数据。

一篇关于在 MS-SQL 中动态创建交叉表查询的好文章。这是一个黑客,但看起来它应该工作。

否则,更灵活的方法是...

Select Distinct
Item,
Time Sold,
Count([Item])
From
MyTable
Group By
Item,
Time Sold

这会给你:

    项目 | 售出时间 | 数数
    ----------------------
    一个 | 05/2010 | 2
    一个 | 04/2010 | 1
    乙| 04/2010 | 1
    C | 03/2010 | 1

这是一种更好的数据分析格式,因为您可以编写查询来处理已知列名的数据。

例如,您可以在报告工具中使用此数据来:

  • 计算所有已售出的物品
  • 显示不同的日期列表
  • 显示哪些日期售出商品最多的列表

要将其转换为您要求的报告格式,您最好使用诸如 Crystal Reports 或 Excel 之类的报告工具。

Excel 和 Crystal Report 都支持数据透视表,以便以您请求的表格格式显示数据(而且它看起来也会好很多!)。

于 2010-08-18T13:14:46.967 回答
1

group by可以获得每个项目的汇总结果。使用sumcase,您可以计算特定时期内的项目数。例如:

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
于 2010-08-18T13:16:19.240 回答