【问题标题】:Show 0 for null rows为空行显示 0
【发布时间】:2016-05-09 16:05:40
【问题描述】:

我正在处理一个比较查询,它将比较针对不同信用卡类型处理的内容与我们的 POS 服务实际处理的内容。我遇到了一个问题,如果某些卡类型在给定日期没有处理任何付款但可能已经退款,我看不到它们的行。 IE:没有使用 VISA 购买任何东西,但获得了 VISA 退款,但由于没有购买,即使该类型有退款,该行也不会显示。

这是我的查询:

WITH tran_total AS (
SELECT  CONCAT(c.id_str, ' - ', c.clinic_str) AS Clinics, 
        t.clinic, 
        c.xcharge_mid, 
        p.pay_desc, 
        CAST(t.time_ran AS date) AS tran_date, 
        CASE WHEN SUM(t.amount) <> 0 THEN SUM(t.amount) * - 1 
        ELSE 0.00 END AS collection
FROM dbo.transactions AS t INNER JOIN
dbo.clinic_master AS c ON t.clinic = c.clinic INNER JOIN
dbo.paytype AS p ON t.clinic = p.clinic AND t.paytype_id = p.paytype_id
WHERE (t.time_ran > GETDATE() - 10) 
AND (t.paytype_id IS NOT NULL) 
AND (p.pay_desc = 'Visa' OR
p.pay_desc = 'MasterCard' OR
p.pay_desc = 'American Express' OR
p.pay_desc = 'Discover')
GROUP BY c.id_str, c.clinic_str, t.clinic, c.xcharge_mid, p.pay_desc, CAST(t.time_ran AS date))
SELECT  w.Clinics, 
        w.pay_desc, 
        w.tran_date, 
        w.collection, 
        CASE WHEN w.pay_desc = 'Visa' THEN (SUM(VI_pur) - SUM(VI_ref)) 
        WHEN w.pay_desc = 'MasterCard' THEN (SUM(MC_pur) - SUM(MC_ref)) 
        WHEN w.pay_desc = 'American Express' THEN (SUM(AX_pur) - SUM(AX_ref)) 
        WHEN w.pay_desc = 'Discover' THEN (SUM(DI_pur) - SUM(DI_ref)) END AS xcharge
FROM            tran_total AS w LEFT OUTER JOIN
dbo.xcharge AS x ON w.xcharge_mid = x.xcharge_mid AND w.tran_date = x.settle_date
GROUP BY w.Clinics, w.pay_desc, w.tran_date, w.collection
ORDER BY w.Clinics, w.tran_date

我曾考虑过切换它并从xcharge 表中的比较开始,但没有pay_desc 可以轻松链接它们,并且如果某些内容被处理为错误卡(选择了VISA,但Discover 是扫描)然后我觉得这些行仍然会丢失。

我想要的是,即使 SUM(t.amount) 没有值,所有 pay_desc 也会出现在每个 tran_date 上。我已经尝试了一个案例语句来完成这个没有任何运气。

编辑:我觉得问题更多是由于t.time_ran 变量。如果给定的pay_desc 没有付款,那么也不会有t.time_ran,我可以做一个函数来列出 GETDATE()-10 和 GETDATE() 之间的日期吗?只是让t.time_ran 和x.settle_date 与该变量匹配?

对此有什么想法吗?提前致谢

更新:

我创建了一个包含各个日期的日历表,并尝试了以下查询:

WITH tran_test AS(
SELECT  cal.calendardate AS cd, 
        p.clinic, 
        p.pay_desc,
        p.paytype_id
FROM calendar cal, paytype p
WHERE cal.calendardate BETWEEN GETDATE()-10 AND GETDATE()+1
AND (p.pay_desc = 'Visa' OR
p.pay_desc = 'MasterCard' OR
p.pay_desc = 'American Express' OR
p.pay_desc = 'Discover'))
SELECT  w.cd, 
        CONCAT(c.id_str, ' - ', c.clinic_str) AS Clinics, 
        w.pay_desc, 
        ISNULL(SUM(t.amount)*-1, 0) AS collection,
        CASE WHEN w.pay_desc = 'Visa' THEN (SUM(x.VI_pur) - SUM(x.VI_ref)) 
        WHEN w.pay_desc = 'MasterCard' THEN (SUM(x.MC_pur) - SUM(x.MC_ref)) 
        WHEN w.pay_desc = 'American Express' THEN (SUM(x.AX_pur) - SUM(x.AX_ref)) 
        WHEN w.pay_desc = 'Discover' THEN (SUM(x.DI_pur) - SUM(x.DI_ref)) END AS xcharge
FROM tran_test w
INNER JOIN clinic_master c
    ON (w.clinic=c.clinic)
LEFT OUTER JOIN transactions t
    ON (t.clinic=w.clinic AND t.paytype_id=w.paytype_id AND CAST(t.time_ran AS date) = w.cd)
LEFT OUTER JOIN xcharge x
    ON (w.cd=x.settle_date AND c.xcharge_mid=x.xcharge_mid)
GROUP BY w.cd, c.id_str, c.clinic_str, w.pay_desc
ORDER BY w.cd

但是,我没有遇到问题,我的 xcharge 列似乎将自身乘以随机间隔,我不知道为什么。

【问题讨论】:

  • 感谢您提供链接,但我也尝试了ISNULL (SUM(t.amount)*-1, 0) AS collections,结果与不显示行的结果相同
  • 不,它只是一个有paytype_id 键的表,pay_desc 是ID 的描述,例如VISA、Cash、Check、Discover 等。
  • 你有两个选择,不要透露哪些列和表有什么

标签: sql sql-server tsql


【解决方案1】:

听起来您需要的是日历表。您可以生成一个作为 CTE 的一部分(此站点上的许多示例或仅搜索 Google),但 IMO 您应该在数据库中有一个持久表。通过这种方式,您可以将某些日子标记为银行假日、您的企业认为它们在哪个季度等。

一旦你有了那个表,你就可以从那个表中SELECT你的日期,然后从你的Transactions表中LEFT OUTER JOIN到那个表。 Transactions 中没有匹配行的任何日期仍将显示一行,但您的 SUM 将有 0.00 值。

【讨论】:

  • 听起来肯定行得通,我会为当年创建一个快速表进行测试,然后生成其余部分并通知结果。
猜你喜欢
  • 1970-01-01
  • 2023-01-12
  • 2012-01-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多