SQL - 有命令可以做到这一点吗?

发布于 2024-09-15 06:33:22 字数 769 浏览 4 评论 0原文

我有一张表,目前是一长串设备及其销售时间的信息。我需要采用看起来像这样的表格:

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

编辑

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

I have a table that currently is a long list of devices and information about when they were sold. I need to take the table which would look something like this:

Item   |  Time Sold
--------------------
  A        05/2010
  B        04/2010
  C        03/2010
  A        04/2010
  A        05/2010

And then have a table with the item as the first column, with the count of the dates being the column headers, like below:

Item   |   Count_03/2010   |  Count_04/2010  |  Count_05/2010
-------------------------------------------------------------
  A    |         0         |         1       |        2
  B    |         0         |         1       |        0
  C    |         1         |         0       |        0

Is there a simple way of doing this? I know in other languages there is a single command to do it, was wondering if SQL had one.

EDIT

My problem is that there is more than one table, and in some tables the months may be different than in other tables. Is there anyway to write a script that will apply to them all, by getting the variables listed and then using those to create the columns in the code? I could write one if I knew the months would always be the same, but since they are variable, is there a way of doing this.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

夏见 2024-09-22 06:33:22

SQL Server 2005 及更高版本有一个名为pivot 的功能,但它仍然不是一个命令,您需要知道“销售时间”列中的值。您可以使用动态透视方法,如 Itzik Ben-Gan 在他的 Inside Microsoft SQL Server 中演示的那样2008:T-SQL 查询图书

示例

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

SQL Server 2005 and up has something called pivot, but it is still not one command and you need to know the values in the Time sold column. You can use a dynamic pivot approach as demonstrated by Itzik Ben-Gan in his Inside Microsoft SQL Server 2008: T-SQL Querying book

Example

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
小鸟爱天空丶 2024-09-22 06:33:22

我没有测试它,但以下应该有效。我使用子查询来获得所需的结果:

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;

I didn't test it, but the following should work. I uses subqueries to get the desired results:

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;
永不分离 2024-09-22 06:33:22

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

有一个 关于在 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 都支持数据透视表,以您请求的表格格式显示数据(而且看起来也会更好!)。

Natively MS-SQL does not provide any functionality to display data in the tabular format you want without knowing the values you want to generate the column names from.

There is a great article on dynamically creating crosstab queries in MS-SQL. It's a hack, but looks like it should work.

Otherwise a more flexible approach is to do...

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

This will give you:

    Item | Time Sold | Count
    ------------------------
    A    | 05/2010   | 2
    A    | 04/2010   | 1
    B    | 04/2010   | 1
    C    | 03/2010   | 1

This is a much better format to work with for data analysis, as you can write a query to handle the data as the column names are known.

For example, you can use this data in a reporting tool to:

  • Count all of the sold items
  • Show a distinct list of dates
  • Show a list of which dates had the most items sold

To get it into the report format you have requested, you're better off using a reporting tool such as Crystal Reports or Excel even.

Both Excel and Crystal Report support Pivot tables for displaying your data in the tabular format you request (and it'll look a lot nicer too!).

清音悠歌 2024-09-22 06:33:22

您可以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

You can group by to get aggregated results per item. Using sum and case, you can count the number of items in a specific period. For example:

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

If you have source tables in multiple formats, union them together in a subquery. I'll limit this example to only one range to save space:

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文