Reputation: 329
I'm working on a comparison query that will compare what was processed for the different credit card types versus what was actually processed by our POS service. I have ran into an issue where I am not seeing rows for certain card types if they did not process any payments on a given day but may have given a refund. IE: Nothing purchased with VISA but a VISA refund was given, but due to no purchases the row does not show up even though there's a refund for that type.
Here is my query:
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
I've thought about switching this around and starting with the comparison from the xcharge
table but there is not a pay_desc
that links those easily and if something is processed as the wrong card (VISA is chosen but Discover is scanned) then I feel the rows would be missed still.
What I would like, is for all of the pay_desc
to show up for each tran_date
even if the SUM(t.amount)
does not have a value. I've tried a case statement to accomplish this without any luck.
EDIT: I feel the issue is more due to the t.time_ran
variable. If there isn't a payment for a given pay_desc
then there won't be a t.time_ran
either, is there a function I can do to list out dates between GETDATE()-10 AND GETDATE() kind of thing and just have the t.time_ran
and x.settle_date
match up to that variable instead?
Any thoughts on this? Thanks in advance
UPDATE:
I have created a calendar table with individual dates and have tried the following query:
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
However, I'm not getting an issue where my xcharge
column seems to multiplying itself by random intervals and I'm not sure why.
Upvotes: 0
Views: 209
Reputation: 47444
It sounds like what you need is a Calendar table. You can generate one as part of a CTE (many examples on this site or just search Google), but IMO you should have a persistent table in your database. This way you can mark certain days as bank holidays, what quarter your business considers them to be in, etc.
Once you have that table in place you can SELECT
your dates from that table and then LEFT OUTER JOIN
to that table from your Transactions
table. Any dates without matching rows in Transactions
will still show up with a row, but you'll have 0.00 value for your SUM
.
Upvotes: 1