How to troubleshooting the Sql test queries of on-prime and synapse - sql

I am new to ETL testing, and I am comparing the 7 and 90 days data between on-prime and synapse,
The query Was written by my lead, but He left the project.
This is my on-prime Query,
Select s.StoreNumber,
rt.Description As RecordType,
rt.IsReturn,
Sum(tm.Amount) As TotalSales,
Sum(tm.Quantity) As TotalSalesQty
From pos.Ticket t Join pos.TicketSegment ts
On t.TicketKey = ts.TicketKey
Join pos.TicketMerchandise tm
On tm.TicketKey = ts.TicketKey
And tm.TicketSegmentKey = ts.TicketSegmentKey
Join org.Store s
On t.StoreKey = s.StoreKey
Join pos.RecordType rt
On tm.RecordTypeKey = rt.RecordTypeKey
Where t.BusinessDate = Dateadd(day,-90, getdate()) and t.BusinessDate< getdate()
Group By s.StoreNumber,
rt.Description,
rt.IsReturn
UNION ALL
Select s.StoreNumber,
rt.Description As RecordType,
rt.IsReturn,
Sum(tdi.DiscountAmount) As TotalSales,
Sum(td.Quantity) As TotalSalesQty
From pos.Ticket t Join pos.TicketSegment ts
On t.TicketKey = ts.TicketKey
Join pos.TicketDiscount td
On td.TicketKey = ts.TicketKey
And td.TicketSegmentKey = ts.TicketSegmentKey
Join pos.TicketDiscountItem tdi
On tdi.TicketDiscountKey = td.TicketDiscountKey
Join org.Store s
On t.StoreKey = s.StoreKey
Join pos.RecordType rt
On td.RecordTypeKey = rt.RecordTypeKey
Where t.BusinessDate >= Dateadd(day,-90, getdate()) and t.BusinessDate < getdate()
Group By s.StoreNumber,
rt.Description,
rt.IsReturn
Order By s.StoreNumber,
rt.Description,
rt.IsReturn
This is my synapse query:
Select s.StoreNumber,
tt.TransactionType,
tt.IsReturn,
Sum(Convert(Money, f.Amount)) As TotalSales,
Sum(f.Qty) As TotalSalesQty
From fact.PrdTransaction f
Join dim.Calendar c
On f.DateID = c.DateID
Join dim.Store s
On f.StoreID = s.StoreID
Join dim.TransactionType tt
On f.TransactionTypeID = tt.TransactionTypeID
Where c.Date>= DATEADD(day,-90, getdate()) and c.Date< getDate()
Group By s.StoreNumber,
tt.TransactionType,
tt.IsReturn
Order By s.StoreNumber,
tt.TransactionType,
tt.IsReturn
When I compared both results, I got some differences for the 7 days trailing period of TotalsalesQty and 90 days trailing period is a little more different than 7 days for TotalSales and TotalSlaesQty.
I am struggling to troubleshoot the difference, where the problem is.
Please help me to troubleshoot this.

Related

Order by on a nested query

Is their a way to order this by the Time column? I am not sure how to do this. The time is the schedule and I just need it to go from the morning to the evening.
Can I just nest another select statement and use that?
Thank you.
SELECT
DoseLevel,
LastName,
FirstName,
DOB,
EMPLID,
Time,
(
SELECT v.ColorCode
FROM ABCDocumentation cd1
LEFT JOIN ABCDocumentation cd2ON cd1.ABCDocumentationID = cd2.PairID
LEFT JOIN Medicine v ON v.MedicineID = cd1.MedicineID
LEFT JOIN Manufacturers mfg ON v.MFG_Seq = mfg.MFG_Seq
WHERE cd2.ABCDocumentationID = dt.ABCDocumentationID
) AS ParentColorCode,
(
SELECT mfg.Description
FROM ABCDocumentation cd1
LEFT JOIN ABCDocumentation cd2 ON cd1.ABCDocumentationID = cd2.PairID
LEFT JOIN Medicine v ON v.MedicineID = cd1.MedicineID
LEFT JOIN Manufacturers mfg ON v.MFG_Seq = mfg.MFG_Seq
WHERE cd2.ABCDocumentationID = dt.ABCDocumentationID
) AS ParentManuDesc
FROM
(
SELECT
cd.DoseLevel,
e.LastName,
e.FirstName,
e.DOB,
cvse.EMPLID,
cvse.AdminScheduleSlotsEmployeeID,
cd.ABCDocumentationID,
cvss.Time,
cd.ModifyDate AS 'StartTime'
FROM ABCAdminSchedule cvs
LEFT JOIN ABCAdminScheduleSlots cvss ON cvs.AdminScheduleID = cvss.AdminScheduleID
LEFT JOIN ABCAdminScheduleSlotsEmployee cvse ON cvss.AdminScheduleSlotsID = cvse.AdminScheduleSlotsID
LEFT JOIN ABCDocumentation cd ON cvse.AdminScheduleSlotsEmployeeID = cd.AdminScheduleSlotsEmployeeID
LEFT JOIN Employee e ON cvse.EmplID = e.EMPLID
WHERE CAST(TIME AS Date) = CAST(GETDATE() AS Date) AND CampusID = '06'
AND cvse.AdminScheduleSlotsEmployeeID IS NOT NULL
) dt
First off, there is no need for the derived table dt, as you are not doing any further processing.
Secondly, you can combine the two correlated subqueries into one with an APPLY.
Thirdly, conversions on columns can cause performance issues, so you can change the date check to a half-open interval, converting just GETDATE().
Finally you can add at the end an ORDER BY clause to sort.
SELECT
cd.DoseLevel,
e.LastName,
e.FirstName,
e.DOB,
cvse.EMPLID,
cvss.Time,
Parent.ColorCode,
Parent.Description
FROM ABCAdminSchedule cvs
LEFT JOIN ABCAdminScheduleSlots cvss ON cvs.AdminScheduleID = cvss.AdminScheduleID
LEFT JOIN ABCAdminScheduleSlotsEmployee cvse ON cvss.AdminScheduleSlotsID = cvse.AdminScheduleSlotsID
LEFT JOIN ABCDocumentation cd ON cvse.AdminScheduleSlotsEmployeeID = cd.AdminScheduleSlotsEmployeeID
LEFT JOIN Employee e ON cvse.EmplID = e.EMPLID
OUTER APPLY
(
SELECT v.ColorCode, mfg.Description
FROM ABCDocumentation cd1
LEFT JOIN ABCDocumentation cd2ON cd1.ABCDocumentationID = cd2.PairID
LEFT JOIN Medicine v ON v.MedicineID = cd1.MedicineID
LEFT JOIN Manufacturers mfg ON v.MFG_Seq = mfg.MFG_Seq
WHERE cd2.ABCDocumentationID = dt.ABCDocumentationID
) AS Parent
WHERE TIME >= CAST(GETDATE() AS Date) AND TIME < CAST(DATEADD(day, 1, GETDATE()) AS DATE)
AND CampusID = '06'
AND cvse.AdminScheduleSlotsEmployeeID IS NOT NULL
ORDER BY TIME
please
declare #tm table (id int identity, timee time(7))
insert into #tm (timee) values ('01:05:45'),
('10:15:18'),
('14:18:59'),
('09:15:10'),
('18:19:21'),
('21:05:17')
this is a default
select * from #tm order by id
this is a, what do you need
select tm.*,
iif(tm.part_time = 1, 'morning', 'evening') m_e from (select
case
when timee between '09:00:00' and '19:00:00' then 1
else 2 end part_time,
*
from #tm) tm
order by part_time, timee

SQL Server Query Indicating Amount sold over 3 different time periods

I am trying to write a SQL query that selects from a table some data. The data I want includes how many times an item has sold and the goal is to have columns have that indicate how many times the item has sold in 30,60, and 90 days. I can write 3 separate queries that do the job but I would like to write one query so the data is all on one resulting table. This is what I have so far:
DECLARE #30daysago DATETIME = DATEADD(DAY,-30,CAST(GETDATE() AS DATE));
DECLARE #90daysago DATETIME = DATEADD(DAY,-90,CAST(GETDATE() AS DATE));
Set NOCOUNT ON
Select company_info_1 from setup
select ii.itemnum, i.itemname,i.price, d.description, count(ii.itemnum)
from invoice_itemized ii
join invoice_totals IT on it.invoice_number=ii.invoice_number
join inventory i on i.itemnum=ii.itemnum
join departments d on d.dept_id=i.dept_id
where it.datetime > #30daysago and len(ii.itemnum) >4
group by ii.itemnum, i.itemname, d.description, i.price
order by count(ii.itemnum) desc
Use a single query with conditional aggregation:
SELECT
ii.itemnum,
i.itemname,
i.price,
d.description,
COUNT(ii.itemnum) AS total,
COUNT(CASE WHEN it.datetime > DATEADD(DAY, -30, CAST(GETDATE() AS DATE))
THEN ii.itemnum END) AS 30daysago,
COUNT(CASE WHEN it.datetime > DATEADD(DAY, -90, CAST(GETDATE() AS DATE))
THEN ii.itemnum END) AS 90daysago
FROM invoice_itemized ii
INNER JOIN invoice_totals IT
ON it.invoice_number = ii.invoice_number
INNER JOIN inventory I
ON i.itemnum = ii.itemnum
INNER JOIN departments d
ON d.dept_id = i.dept_id
WHERE
LEN(ii.itemnum) > 4
GROUP BY
ii.itemnum,
i.itemname,
d.description,
i.price
ORDER BY
ii.itemnum DESC;

Selecting top result of each category of product

Below query is pulling back the data below.
I am trying to only return one single result for each product number, with only the highest orddate, and it related order total (ordttl) and unit cost (ucost).
Ideas on implementing? Thanks for any responses.
SELECT
ordln.pnum as 'Product Number',
prod.name as 'Product Name',
ordhd.snum,
sup.name,
ordhd.ordttl,
ORDHD.onum,
ORDHD.orddate,
ordln.ucost
FROM
scmdb.dbo.cksprodm prod (NOLOCK)
INNER JOIN scmdb.dbo.cksordln ordln (NOLOCK) on prod.pnum = ordln.pnum
INNER JOIN scmdb.dbo.cksordhd ordhd (NOLOCK) on ordhd.onum = ordln.onum
LEFT JOIN scmdb.dbo.ckssuplr sup (NOLOCK) on ordhd.snum = coalesce(sup.snum,
sup.asnum)
WHERE ordhd.orddate BETWEEN
DATEADD(month,-6,dateadd(day,datediff(day,0,getdate()),0) + '06:00') AND
GETDATE() -- order date is between 6 months ago and today.
AND ordln.pnum NOT IN (SELECT distinct PNUM
FROM scmdb.dbo.cksquohd qhd
inner join scmdb.dbo.cksquoln qln on qhd.quote = qln.quote
where qhd.qedate > GETDATE()
)
You can use row_number to rank by date and get latest date's row:
SELECT *
FROM
(
SELECT
ordln.pnum as 'Product Number',
prod.name as 'Product Name',
ordhd.snum,
sup.name,
ordhd.ordttl,
ORDHD.onum,
ORDHD.orddate,
ordln.ucost,
row_number() over (partition by ordln.pnum order by ORDHD.orddate desc) as ranking
FROM
scmdb.dbo.cksprodm prod (NOLOCK)
INNER JOIN scmdb.dbo.cksordln ordln (NOLOCK) on prod.pnum = ordln.pnum
INNER JOIN scmdb.dbo.cksordhd ordhd (NOLOCK) on ordhd.onum = ordln.onum
LEFT JOIN scmdb.dbo.ckssuplr sup (NOLOCK) on ordhd.snum = coalesce(sup.snum,
sup.asnum)
WHERE ordhd.orddate BETWEEN
DATEADD(month,-6,dateadd(day,datediff(day,0,getdate()),0) + '06:00') AND
GETDATE() -- order date is between 6 months ago and today.
AND ordln.pnum NOT IN (SELECT distinct PNUM
FROM scmdb.dbo.cksquohd qhd
inner join scmdb.dbo.cksquoln qln on qhd.quote = qln.quote
where qhd.qedate > GETDATE()
)
) t
where ranking = 1

SUM RESULTS OF CASE STATEMENTS

I've this query working fine. I need to have the sum of the column "piedini". Can you help me to undestand how to do? I obtain X row for each "Lunghezza" (lenght) that the query find. I'm not interested to this field but only to the sum o column "piedini" created from the CASE SUM.
SELECT
EXTRAMAG.PRS_LUNGHEZZA,SUM(RIGHEDOCUMENTI.QTAGEST) AS TAVOLI, CASE WHEN EXTRAMAG.PRS_LUNGHEZZA < '2000' THEN SUM(RIGHEDOCUMENTI.QTAGEST)*4 ELSE SUM(RIGHEDOCUMENTI.QTAGEST)*6 END AS PIEDINI
FROM dbo.TESTEDOCUMENTI
INNER JOIN dbo.ANAGRAFICACF
ON CODCLIFOR=CODCONTO
INNER JOIN dbo.RIGHEDOCUMENTI
ON PROGRESSIVO=IDTESTA AND TOTNETTORIGA <>'0' AND RIGHEDOCUMENTI.DESCRIZIONEART LIKE '%TAVOL%'
INNER JOIN dbo.EXTRAMAG
ON RIGHEDOCUMENTI.CODART=EXTRAMAG.CODART
LEFT JOIN .dbo.ANAGRAFICAAGENTI
ON CODAGENTE=CODAGENTE1
LEFT JOIN dbo.TABPAGAMENTI
ON CODPAGAMENTO = CODICE
WHERE dbo.TESTEDOCUMENTI.DOCCHIUSO = '0' AND dbo.TESTEDOCUMENTI.BLOCCATO = '0' AND dbo.TESTEDOCUMENTI.TIPODOC = 'ORC' AND TESTEDOCUMENTI.DATACONSEGNA BETWEEN DATEADD(DAY, -60, GETDATE()) AND GETDATE()
GROUP BY EXTRAMAG.PRS_LUNGHEZZA
Try the below :
select sum(PIEDINI) from (
SELECT XTRAMAG.PRS_LUNGHEZZA,SUM(RIGHEDOCUMENTI.QTAGEST) AS TAVOLI, CASE WHEN EXTRAMAG.PRS_LUNGHEZZA < '2000' THEN SUM(RIGHEDOCUMENTI.QTAGEST)*4 ELSE SUM(RIGHEDOCUMENTI.QTAGEST)*6 END AS PIEDINI
FROM dbo.TESTEDOCUMENTI
INNER JOIN dbo.ANAGRAFICACF
ON CODCLIFOR=CODCONTO
INNER JOIN dbo.RIGHEDOCUMENTI
ON PROGRESSIVO=IDTESTA AND TOTNETTORIGA <>'0' AND RIGHEDOCUMENTI.DESCRIZIONEART LIKE '%TAVOL%'
INNER JOIN dbo.EXTRAMAG
ON RIGHEDOCUMENTI.CODART=EXTRAMAG.CODART
LEFT JOIN .dbo.ANAGRAFICAAGENTI
ON CODAGENTE=CODAGENTE1
LEFT JOIN dbo.TABPAGAMENTI
ON CODPAGAMENTO = CODICE
WHERE dbo.TESTEDOCUMENTI.DOCCHIUSO = '0' AND dbo.TESTEDOCUMENTI.BLOCCATO = '0' AND dbo.TESTEDOCUMENTI.TIPODOC = 'ORC' AND TESTEDOCUMENTI.DATACONSEGNA BETWEEN DATEADD(DAY, -60, GETDATE()) AND GETDATE()
GROUP BY EXTRAMAG.PRS_LUNGHEZZA
)t

Getting a count for the first six months and last six months of FYear

I need to count all patients who had a service in both the first six months of the year and the last six months of the the fiscal year. This is what I have come up with, but not certain that it will be completely clean.
with sd as
(
select cln.cln_urn, MAX(srv_date) As Last_D, MIN(srv_date) AS First_d
from cw_domain dmn
inner join cw_service srv on srv.srv_dmn_fk=dmn.dmn_pk
inner join cw_client cln on cln.cln_pk=srv.srv_cln_fk
inner join cw_subservice sbs on sbs.sbs_pk=srv.srv_sbs_fk
inner join cw_service_category ct on ct.srv_ct_rpk=sbs.sbs_srv_ct_rfk
WHERE srv.srv_date >= '03/01/2015'
and srv.srv_date <= '02/29/2016'
and srv_ct_rpk = '002'
group by cln_urn
having MAX(srv_date)>= MIN(srv_date)+180
)
select count (distinct cln_urn)
from sd
What is being researched in this report is the number of clients who are keeping up with their treatment. In order for our client base to be considered 'in care' they must see their doctor twice a year: once in the first half and again in the second half of the year
If You want to count how many services each client has had, You need to use count function.
select HalfOfYear
, NumOfPatients = count(Client)
from (select
cln_urn as Client
,case when datepart(q,srv_date) in (1,2) then 'FirstHalf'
when datepart(q,srv_date) in (3,4) then 'SecondHalf'
end as HalfOfYear
from cw_domain dmn
inner join cw_service srv on srv.srv_dmn_fk=dmn.dmn_pk
inner join cw_client cln on cln.cln_pk=srv.srv_cln_fk
inner join cw_subservice sbs on sbs.sbs_pk=srv.srv_sbs_fk
inner join cw_service_category ct on ct.srv_ct_rpk=sbs.sbs_srv_ct_rfk
where srv.srv_date >= '03/01/2015'
and srv.srv_date <= '02/29/2016'
and srv_ct_rpk = '002'
) as x
group by HalfOfYear
This should do the trick. Just swap out the #from and #thru with your dates.
WITH sd AS
(
SELECT
DISTINCT
cln.cln_urn,
CASE
WHEN srv.srv_date < DATEADD(MONTH, 6, #from) THEN 1
WHEN srv.srv_date >= DATEADD(MONTH, 6, #from) THEN 2
END AS 'half'
FROM
cw_domain dmn
INNER JOIN cw_service AS srv
ON srv.srv_dmn_fk = dmn.dmn_pk
INNER JOIN cw_client cln
ON cln.cln_pk = srv.srv_cln_fk
INNER JOIN cw_subservice sbs
ON sbs.sbs_pk = srv.srv_sbs_fk
INNER JOIN cw_service_category ct
ON ct.srv_ct_rpk = sbs.sbs_srv_ct_rfk
WHERE
srv.srv_date >= #from
AND srv.srv_date <= #thru
AND srv_ct_rpk = '002'
)
SELECT
COUNT(cln.cln_urn)
FROM
sd AS fh
JOIN sd AS sh
ON fh.cln_urn = sh.cln_urn
WHERE
fh.half = 1
AND sh.half = 2