SQL如何获取0值

时间:2011-01-18 04:04:20

标签: sql reporting-services

我正在使用此SQL生成下图(RS2008R2):

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)

问题:如何在图表的底部轴上获得稳定的日期时间轴?即我想在此图表中显示大量0列数据,并显示所有日期。

但是,虽然Reporting Services 2008R2可以很好地处理这个问题,但还没有找到一个好的例子。

alt text

3 个答案:

答案 0 :(得分:1)

从表中要显示零值的左连接显示零值。例如,以下显示零值:

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

而以下

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

在这种情况下,您希望为日期显示零值,因此它有点棘手。您可能需要创建一个表或视图,其中包含要显示的日期列表,然后将其连接到您的数据。根据您的要求,在检索数据集之后,在SQL之外执行此操作可能更容易。

答案 1 :(得分:0)

执行此操作可能有一种棘手的方法取决于您的DBMS(例如this one一天中的某些时间),但我发现从Jan开始创建一个包含每个日期的表通常会更容易1,1900年到12月31日,2999。我特别的Y3K问题将由于我将死去并且不太有能力照顾这个事实来解决: - )

然后我将查询重构为该表与数据表本身的连接(或者使用子查询并合并以消除NULL),因此数据表中没有行的日期变为零。 / p>

答案 2 :(得分:0)

首先,您的查询可以更简单地编写

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

最终的解决方案是

;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