2014-12-10 2 views
1

У меня есть таблица с несколькими записями, как показано ниже в sql скрипте.Неверный счет в сводной таблице запроса

Мои данные выборки:

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)) 

Query Я попытался:

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 колонке, которая дает неправильный подсчет в результате.

ответ

3

Проблема заключается в том, что вы не считая AvailableIN для каждого col1, вы в основном получаете общий подсчет DateOne и DateTwo который равен 2, потому что у вас есть 2 значения в test_two. Я бы переписать запрос на нечто похожее на:

;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 | 
+0

Благодарю вас так много. – MAK

Смежные вопросы