SQL How to get 0 values

蓝咒 提交于 2019-12-24 07:57:42

问题


I'm generating the graph below (RS2008R2) using this SQL:

SELECT  Merchant.Name as MerchantName, 
    CONVERT(char(8), 
    VoucherRedemption.RedeemedAtUTC, 112) as ShortDateRedeemed,
    COUNT(CONVERT(char(8), VoucherRedemption.RedeemedAtUTC, 112)) as NumberRemeemedOnDay
FROM    Merchant 
INNER JOIN  Terminal ON Merchant.MerchantUID = Terminal.MerchantUID 
INNER JOIN  VoucherRedemption ON Terminal.TerminalUID = VoucherRedemption.TerminalUID
WHERE       Merchant.Name = 'Merchant 1'
GROUP BY    merchant.Name, 
            CONVERT(char(8), VoucherRedemption.RedeemedAtUTC, 112)

Question: How do I get a steady date timeline on the bottom axis of the graph? ie I want to show a lot of 0 column data in this graph with all dates showing.

A though is that Reporting Services 2008R2 may handle this well, but haven't found a good example yet.


回答1:


To begin with, your query can be written more simply

SELECT  Merchant.Name as MerchantName, 
    CONVERT(char(8), VoucherRedemption.RedeemedAtUTC, 112) as ShortDateRedeemed,
    COUNT(VoucherRedemption.RedeemedAtUTC) as NumberRemeemedOnDay
FROM    Merchant 
INNER JOIN  Terminal ON Merchant.MerchantUID = Terminal.MerchantUID 
INNER JOIN  VoucherRedemption ON Terminal.TerminalUID = VoucherRedemption.TerminalUID
WHERE       Merchant.Name = 'Merchant 1'
GROUP BY    merchant.Name,  VoucherRedemption.RedeemedAtUTC

The final solution would be

;with tmp as (
    SELECT  Merchant.Name as MerchantName, 
        VoucherRedemption.RedeemedAtUTC as ShortDateRedeemed,
        COUNT(VoucherRedemption.RedeemedAtUTC) as NumberRemeemedOnDay
    FROM    Merchant 
    INNER JOIN  Terminal ON Merchant.MerchantUID = Terminal.MerchantUID 
    INNER JOIN  VoucherRedemption ON Terminal.TerminalUID = VoucherRedemption.TerminalUID
    WHERE       Merchant.Name = 'Merchant 1'
    GROUP BY    merchant.Name,  VoucherRedemption.RedeemedAtUTC
), dates as (
    select min(ShortDateRedeemed) theDate, max(ShortDateRedeemed) endDate
    from tmp
    union all
    select theDate + 1, endDate
    from dates
    where theDate < endDate
)
SELECT  A.MerchantName, 
        CONVERT(char(8), theDate, 112) as ShortDateRedeemed,
        isnull(A.NumberRemeemedOnDay,0)
FROM dates B
left join tmp A on B.theDate = A.ShortDateRedeemed



回答2:


Zero values are shown by left joining from the table that you want to show zero values from. For example, the following will not show zero values:

SELECT Users.name, COUNT(UserLoginHistory.*) AS Logins
FROM Users
INNER JOIN UserLoginHistory ON Users.id = UserLoginHistory.user_id
GROUP BY Users.name

whereas the following will:

SELECT Users.name, COUNT(UserLoginHistory.*) AS Logins
FROM Users
LEFT JOIN UserLoginHistory ON Users.id = UserLoginHistory.user_id
GROUP BY Users.name

In this case you want to show zero values for dates so it's a little trickier. You may need to create a table or view that has the list of dates you want to show then left join that to your data. Depending on your requirements, it may be easier to do this outside of SQL after you have retrieved the dataset.




回答3:


There's probably a tricky way of doing this that depends on your DBMS (such as this one for times of the day) but I've found it's often easier just to create a table with every date in it from Jan 1, 1900 through to Dec 31, 2999. My particular Y3K problem will be fixed by the fact that I'll be dead and not very capable of caring :-)

Then I restructure my query as a join of that table against the data table itself (or with the use of sub-queries and coalesce to get rid of NULLs), hence dates with no rows in the data table get zero.



来源:https://stackoverflow.com/questions/4720381/sql-how-to-get-0-values

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!