【问题标题】:Incorrect count in pivot table query数据透视表查询中的计数不正确
【发布时间】:2014-12-10 04:42:18
【问题描述】:

我在 sql fiddle 中有两个表,其中包含一些记录,如下所示。

我的样本数据是:

CREATE TABLE [dbo].[test_One](
    [ID] [varchar](10) NULL,
    [Col1] [varchar](20) NULL,
    [Col2] [varchar](20) NULL,
    [ColumnDate] [datetime] NULL,
    [ColumnTime] [time](7) NULL
)

CREATE TABLE [dbo].[test_two](
    [Slno] [varchar](10) NULL,
    [ID] [varchar](10) NULL,
    [Name] [varchar](max) NULL,
    [Date1] [datetime] NULL,
    [Time1] [datetime] NULL,
    [Date2] [datetime] NULL,
    [Time2] [datetime] NULL
) 

INSERT [dbo].[test_two] ([Slno], [ID], [Name], [Date1], [Time1], [Date2], [Time2]) VALUES (N'115', N'47', N'DateOne', CAST(0x0000901A00000000 AS DateTime), CAST(0x0000000000000000 AS DateTime), CAST(0x0000901B00000000 AS DateTime), CAST(0x00000000018B3BB0 AS DateTime))
INSERT [dbo].[test_two] ([Slno], [ID], [Name], [Date1], [Time1], [Date2], [Time2]) VALUES (N'116', N'47', N'DateTwo', CAST(0x0000901C00000000 AS DateTime), CAST(0x0000000000000000 AS DateTime), CAST(0x0000901D00000000 AS DateTime), CAST(0x00000000018B3BB0 AS DateTime))

INSERT [dbo].[test_One] ([ID], [Col1], [Col2], [ColumnDate], [ColumnTime]) VALUES (N'47', N'11601', N'782', CAST(0x0000901A00000000 AS DateTime), CAST(0x070075033F430000 AS Time))
INSERT [dbo].[test_One] ([ID], [Col1], [Col2], [ColumnDate], [ColumnTime]) VALUES (N'47', N'11602', N'504', CAST(0x0000901A00000000 AS DateTime), CAST(0x07809A19CB4B0000 AS Time))
INSERT [dbo].[test_One] ([ID], [Col1], [Col2], [ColumnDate], [ColumnTime]) VALUES (N'47', N'11603', N'110', CAST(0x0000901A00000000 AS DateTime), CAST(0x0700C02F57540000 AS Time))
INSERT [dbo].[test_One] ([ID], [Col1], [Col2], [ColumnDate], [ColumnTime]) VALUES (N'47', N'11604', N'634', CAST(0x0000901A00000000 AS DateTime), CAST(0x0780E545E35C0000 AS Time))
INSERT [dbo].[test_One] ([ID], [Col1], [Col2], [ColumnDate], [ColumnTime]) VALUES (N'47', N'11601', N'400', CAST(0x0000901B00000000 AS DateTime), CAST(0x07002D2255650000 AS Time))
INSERT [dbo].[test_One] ([ID], [Col1], [Col2], [ColumnDate], [ColumnTime]) VALUES (N'47', N'11601', N'376', CAST(0x0000901B00000000 AS DateTime), CAST(0x07804A62F8430000 AS Time))
INSERT [dbo].[test_One] ([ID], [Col1], [Col2], [ColumnDate], [ColumnTime]) VALUES (N'47', N'11602', N'989', CAST(0x0000901B00000000 AS DateTime), CAST(0x07007078844C0000 AS Time))
INSERT [dbo].[test_One] ([ID], [Col1], [Col2], [ColumnDate], [ColumnTime]) VALUES (N'47', N'11602', N'949', CAST(0x0000901B00000000 AS DateTime), CAST(0x0780958E10550000 AS Time))
INSERT [dbo].[test_One] ([ID], [Col1], [Col2], [ColumnDate], [ColumnTime]) VALUES (N'47', N'11603', N'111', CAST(0x0000901C00000000 AS DateTime), CAST(0x0700DD6A825D0000 AS Time))
INSERT [dbo].[test_One] ([ID], [Col1], [Col2], [ColumnDate], [ColumnTime]) VALUES (N'47', N'11603', N'840', CAST(0x0000901C00000000 AS DateTime), CAST(0x078002810E660000 AS Time))
INSERT [dbo].[test_One] ([ID], [Col1], [Col2], [ColumnDate], [ColumnTime]) VALUES (N'47', N'11603', N'217', CAST(0x0000901C00000000 AS DateTime), CAST(0x070020C1B1440000 AS Time))
INSERT [dbo].[test_One] ([ID], [Col1], [Col2], [ColumnDate], [ColumnTime]) VALUES (N'47', N'11604', N'420', CAST(0x0000901C00000000 AS DateTime), CAST(0x078045D73D4D0000 AS Time))
INSERT [dbo].[test_One] ([ID], [Col1], [Col2], [ColumnDate], [ColumnTime]) VALUES (N'47', N'11604', N'333', CAST(0x0000901D00000000 AS DateTime), CAST(0x07008DB3AF550000 AS Time))
INSERT [dbo].[test_One] ([ID], [Col1], [Col2], [ColumnDate], [ColumnTime]) VALUES (N'47', N'11604', N'782', CAST(0x0000901D00000000 AS DateTime), CAST(0x0780B2C93B5E0000 AS Time))
INSERT [dbo].[test_One] ([ID], [Col1], [Col2], [ColumnDate], [ColumnTime]) VALUES (N'47', N'11604', N'504', CAST(0x0000901D00000000 AS DateTime), CAST(0x0700D8DFC7660000 AS Time))
INSERT [dbo].[test_One] ([ID], [Col1], [Col2], [ColumnDate], [ColumnTime]) VALUES (N'47', N'11604', N'110', CAST(0x0000901D00000000 AS DateTime), CAST(0x0780F51F6B450000 AS Time))
INSERT [dbo].[test_One] ([ID], [Col1], [Col2], [ColumnDate], [ColumnTime]) VALUES (N'47', N'11601', N'634', CAST(0x0000901E00000000 AS DateTime), CAST(0x07003DFCDC4D0000 AS Time))
INSERT [dbo].[test_One] ([ID], [Col1], [Col2], [ColumnDate], [ColumnTime]) VALUES (N'47', N'11604', N'400', CAST(0x0000901E00000000 AS DateTime), CAST(0x0780621269560000 AS Time))
INSERT [dbo].[test_One] ([ID], [Col1], [Col2], [ColumnDate], [ColumnTime]) VALUES (N'47', N'11601', N'376', CAST(0x0000901E00000000 AS DateTime), CAST(0x07008828F55E0000 AS Time))
INSERT [dbo].[test_One] ([ID], [Col1], [Col2], [ColumnDate], [ColumnTime]) VALUES (N'47', N'11601', N'989', CAST(0x0000901E00000000 AS DateTime), CAST(0x070047936D670000 AS Time))
INSERT [dbo].[test_One] ([ID], [Col1], [Col2], [ColumnDate], [ColumnTime]) VALUES (N'47', N'11603', N'949', CAST(0x0000901F00000000 AS DateTime), CAST(0x078064D310460000 AS Time))
INSERT [dbo].[test_One] ([ID], [Col1], [Col2], [ColumnDate], [ColumnTime]) VALUES (N'47', N'11604', N'111', CAST(0x0000901F00000000 AS DateTime), CAST(0x07008AE99C4E0000 AS Time))
INSERT [dbo].[test_One] ([ID], [Col1], [Col2], [ColumnDate], [ColumnTime]) VALUES (N'47', N'11601', N'840', CAST(0x0000901F00000000 AS DateTime), CAST(0x0700F2ADFE560000 AS Time))
INSERT [dbo].[test_One] ([ID], [Col1], [Col2], [ColumnDate], [ColumnTime]) VALUES (N'47', N'11601', N'217', CAST(0x0000901F00000000 AS DateTime), CAST(0x07005A72605F0000 AS Time))
INSERT [dbo].[test_One] ([ID], [Col1], [Col2], [ColumnDate], [ColumnTime]) VALUES (N'47', N'11601', N'420', CAST(0x0000901F00000000 AS DateTime), CAST(0x0700C236C2670000 AS Time))

我试过的查询:

SELECT col1,Total,TGrp,AvailableIn,[DateOne],[DateTwo],(Total - ([DateOne]+[DateTwo])) as Others
FROM                     
(
    SELECT  v.col1,g.Name as Name,c.Total as Total,
    x.AvailableIn,
    (select count(distinct Name) from test_two) TGrp
    FROM test_one AS v   
    INNER JOIN test_two g ON g.ID= '47' 
    AND ( CONVERT(DATETIME, CONVERT(VARCHAR, v.ColumnDate, 106))
                                                + CONVERT(DATETIME, CONVERT(VARCHAR, v.ColumnTime, 108)) >= g.Date1
                                                + g.Time1
    AND CONVERT(DATETIME, CONVERT(VARCHAR, v.ColumnDate, 106))
                                                + CONVERT(DATETIME, CONVERT(VARCHAR, v.ColumnTime, 108)) <= g.Date2
                                                + g.Time2
                                        )                                                            
    inner join
    (
        select col1,count(*) as Total
        FROM test_one 
        group by col1
    ) c 
    on c.col1 = v.col1
    join
    (
        select ID,count(Available) AS AvailableIn
        from
        (
            select ID,CASE WHEN Name IN('DateOne','DateTwo') THEN 1 END AS Available
            from test_two
        ) as pt
        group by ID
    ) x
    on x.ID= '47'
) p                     
PIVOT                
(            
    count(Name)                        
    FOR Name IN ( [DateOne],[DateTwo] )                        
) AS pvt

SQL 小提琴:http://sqlfiddle.com/#!3/f4678/1

预期结果

col1   Total  TGrp  AvailableIn  DateOne  DateTwo  Others              
---------------------------------------------------------
11601   9      2        1           3        0       6
11602   3      2        1           3        0       0
11603   5      2        2           1        3       1
11604   8      2        2           1        5       2      

上述结果说明AvailableIn 列中的结果是正确的,它显示了可用的组,对于第一行,计数为 1,因为 DateOne 列具有价值。对其他人也是如此。

但得到的结果是:

col1   Total  TGrp  AvailableIn  DateOne  DateTwo  Others              
---------------------------------------------------------
11601   9      2        2           3        0       6
11602   3      2        2           3        0       0
11603   5      2        2           1        3       1
11604   8      2        2           1        5       2      

注意:问题出在AvailableIn 列中,结果中的计数错误。

【问题讨论】:

    标签: sql-server sql-server-2008-r2 pivot


    【解决方案1】:

    问题是你没有计算每个col1AvailableIN,你基本上得到了DateOneDateTwo 的总数,因为test_two 中有2 个值。我会将您的查询重写为类似于:

    ;with data as
    (
        select 
            v.Col1,
            Total = (select count(*) from dbo.test_One t where v.Col1 = t.Col1),
            TGrp = (select count(distinct Name) from test_two),
            g.Name
        from dbo.test_One v
        INNER JOIN test_two g 
            ON g.ID= '47' 
            AND (CONVERT(DATETIME, CONVERT(VARCHAR, v.ColumnDate, 106))
                                                        + CONVERT(DATETIME, CONVERT(VARCHAR, v.ColumnTime, 108)) >= g.Date1
                                                        + g.Time1
            AND CONVERT(DATETIME, CONVERT(VARCHAR, v.ColumnDate, 106))
                                                        + CONVERT(DATETIME, CONVERT(VARCHAR, v.ColumnTime, 108)) <= g.Date2
                                                        + g.Time2
                                                )           
    )
    select 
        Col1,
        Total,
        TGrp,
        AvailableIN,
        DateOne,
        DateTwo,
        Others = (Total - ([DateOne]+[DateTwo]))
    from
    (
        select 
            Col1,
            Total,
            TGrp,
            Name,
            AvailableIN = (select COUNT(distinct name) 
                            from data a 
                            where a.Col1 = d.Col1 
                            group by a.Col1) 
        from data d
    ) src
    pivot
    (
        count(Name)
        for Name in (DateOne, DateTwo)
    ) piv;
    

    SQL Fiddle with Demo。这使用一些相关的子查询来获取每个 col1 值的计数并给出结果:

    |  COL1 | TOTAL | TGRP | AVAILABLEIN | DATEONE | DATETWO | OTHERS |
    |-------|-------|------|-------------|---------|---------|--------|
    | 11601 |     9 |    2 |           1 |       3 |       0 |      6 |
    | 11602 |     3 |    2 |           1 |       3 |       0 |      0 |
    | 11603 |     5 |    2 |           2 |       1 |       3 |      1 |
    | 11604 |     8 |    2 |           2 |       1 |       5 |      2 |
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-09
      • 1970-01-01
      相关资源
      最近更新 更多