簡體   English   中英

SQL Server:強制匯總中所有不同值的結果

[英]SQL Server : force results for all distinct values in aggregate

我試圖強制結果出現在我的結果集中一列的不同值。 換句話說,我希望任何不同的值都顯示為零,而不是在給定的組中沒有值的情況下掉落。

例如,我的數據大致如下:

ID      |Quality | Date     | Dollars
-------------------------------------
1       |Good    | 02/28/15 | 1
2       |Better  | 02/28/15 | 2
3       |Best    | 02/28/15 | 3
4       |*Fair*  | 02/28/15 | 1
1       |Good    | 01/31/15 | 1
2       |Better  | 01/31/15 | 2
3       |Best    | 01/31/15 | 3
1       |Good    | 12/31/15 | 1
3       |Best    | 12/31/15 | 3

我給“ Fair”加注星標以引起注意,因為它會在結果集中引起明顯的“ fair”值。 但是,如果按“日期”分組,“公平”將不會再顯示任何其他月份。

我為解決該問題所做的努力似乎比必要的困難,但是我在弄清楚什么會更簡單時遇到了麻煩。 我想返回該表中最近兩個“日期”的所有不同“質量”結果的總和“美元”。

我已經完成以下工作:

declare @currdt date = '02/28/2015'
declare @prevdt date = DATEADD(d,-1,DATEADD(mm, DATEDIFF(m,0,@currdt),0)) --last day of month prior
declare @dates table (date1 date);

insert into @dates (date1) values (@currdt), (@prevdt);

with qualities (quality, date) as
( 
    select distinct quality, date1
    from mytableA
    join (select * from @dates) a on 1=1
),
history (ID, Quality, Add_Date, Dollars)
(
    select ID, Quality, Add_Date, Dollars
    from mytableA
    where Add_Date <= @currdt
    and Add_Date >= @prevdt
)
select 
    q.quality, q.date, sum(h.Dollars)
from 
    qualities q
left join 
    history h on h.quality = q.quality and h.date = q.date
group by 
    q.quality, q.date

根據上表所示的預期結果應如下:

Quality  | Date     | Dollars
------------------------------
Fair     | 02/28/15 | 1
Good     | 02/28/15 | 1
Better   | 02/28/15 | 2
Best     | 02/28/15 | 3
Fair     | 01/31/15 | 0
Good     | 01/31/15 | 1
Better   | 01/31/15 | 2
Best     | 01/31/15 | 3

我應該在給定的月份中列出一些重復的特質,以使總和更加有趣,但是希望這很清楚。

如果您的目標只是減少查詢長度,那么這應該與您現在所擁有的相同(並且它將輸出兩個日期的所有質量):

declare @currdt date = '02/28/2015'
declare @prevdt date = DATEADD(d,-1,DATEADD(mm, DATEDIFF(m,0,@currdt),0)) --last day of month prior

select a.quality, a.date, sum(isnull(b.Dollars,0)) as dollars
from (select quality, d.date from mytableA, (VALUES (@currdt), (@prevdt)) AS d(date) group by Quality, d.date) a
left join mytableA b on a.Date = b.date and a.Quality = b.Quality
group by a.quality, a.date
order by 2 desc, 3 asc

使用您的樣本數據,將輸出:

quality date        dollars
Fair    2015-02-28  1
Good    2015-02-28  1
Better  2015-02-28  2
Best    2015-02-28  3
Fair    2015-01-31  0
Good    2015-01-31  1
Better  2015-01-31  2
Best    2015-01-31  3

如果您要保持質量的順序( fair -> good -> better -> best ),可以這樣做:

select a.quality, a.date, sum(isnull(b.Dollars,0)) as sum
from (select quality, sort, date from 
    (values (1, 'Fair'), (2, 'Good'), (3, 'Better'), (4, 'Best')) as q(sort, quality), 
    (values (@currdt), (@prevdt)) as d(date) group by q.quality, d.date, sort) a
left join mytableA b on a.Date = b.date and a.Quality = b.Quality
group by a.quality, a.date, sort
order by date desc, sort 

如果我沒有列出質量的另一個表,這就是我會做的方法:

DECLARE @Table TABLE
(
    ID INT IDENTITY
    ,RateableItemID INT
    ,Quality VARCHAR(15)
    ,Date DATE
    ,Dollars MONEY
)
INSERT INTO @Table
(
    RateableItemID 
    ,Quality 
    ,Date 
    ,Dollars 
)
VALUES
(1       ,'Good'    , '02/28/15' , 1 )
,(2       ,'Better'  , '02/28/15' , 2 )
,(3       ,'Best'    , '02/28/15' , 3 )
,(4       ,'Fair'   , '02/28/15' , 1 )
,(1       ,'Good'    , '01/31/15' , 1 )
,(2       ,'Better'  , '01/31/15' , 2 )
,(3       ,'Best'    , '01/31/15' , 3 )
,(1       ,'Good'    , '12/31/15' , 1 )
,(3       ,'Best'    , '12/31/15' , 3 )

SELECT 
    TwoMostRecentDates.Date
    ,Qualities.Quality
    ,ISNULL(SUM(Details.Dollars),0) AS DollarsForThisDateAndQuality
FROM
(
    SELECT DISTINCT TOP 2 
        Date
    FROM
        @Table 
    ORDER BY Date DESC
) TwoMostRecentDates
CROSS JOIN
(
    SELECT DISTINCT 
        Quality
    FROM @Table
) Qualities
LEFT JOIN
    @Table Details
    ON TwoMostRecentDates.Date = Details.Date
    AND Qualities.Quality = Details.Quality
GROUP BY
    TwoMostRecentDates.Date
    ,Qualities.Quality
ORDER BY
    TwoMostRecentDates.Date
    ,CASE
        Qualities.Quality
        WHEN 'Best' THEN 1
        WHEN 'Better' THEN 2
        WHEN 'Good' THEN 3
        WHEN 'Fair' THEN 4
    END

我認為對於所有代碼,可讀性都勝過字符數。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM