Converting NOT in into LEFT join giving incorrect results - sql

Please help me in converting following NOT in query to Left join as I want a date column in select clause. I have to use this query as source to Amazon quicksight. Quicksight cannot pass date paramters created in report to my source query. So I have to get date filtering condition in WHERE clause.
Not in:
SELECT DISTINCT Date(h.Created_Date) DATE, ( h.Vehicle_ID)Decline
FROM awsdatacatalog.waves.Recurring_Transaction_History h
Left JOIN awsdatacatalog.waves.Wash_Invoice wi on h.invoice_id=wi.invoice_id
WHERE Date(h.Created_Date) BETWEEN date('2021-05-01') AND date('2021-05-01')
AND h.Status IN ('Declined','DECLINED')
AND h.Vehicle_ID NOT IN (
SELECT Distinct ut.vehicle_Id
FROM awsdatacatalog.waves.Unlimited_Wash_Transaction ut
WHERE (Is_Refunded IS NULL OR CAST(Is_Refunded AS INTEGER) =0)
AND (Status ='RECURRING' or Status ='RESIGNUP')
AND DATE(DATE) BETWEEN date('2021-05-01') AND date('2021-05-01')
)
Left join query:
SELECT DISTINCT Date(h.Created_Date) DATE, ( h.Vehicle_ID)Decline
FROM awsdatacatalog.waves.Recurring_Transaction_History h
Left JOIN awsdatacatalog.waves.Wash_Invoice wi on h.invoice_id=wi.invoice_id
LEFT JOIN (
SELECT Distinct ut.vehicle_Id, DATE(DATE) DATE
FROM awsdatacatalog.waves.Unlimited_Wash_Transaction ut
WHERE (Is_Refunded IS NULL OR CAST(Is_Refunded AS INTEGER) =0)
AND (Status ='RECURRING' or Status ='RESIGNUP')
) A
ON H.Vehicle_ID = A.Vehicle_ID
AND DATE(h.Created_Date) <= A.DATE
WHERE Date(h.Created_Date) BETWEEN date('2021-05-01') AND date('2021-05-01')
AND A.Vehicle_ID IS NULL
AND A.DATE IS NULL
AND h.Status IN ('Declined','DECLINED')
ORDER BY Date(h.Created_Date) , ( h.Vehicle_ID)

Related

Counting and grouping NULL and non NULL values with count results in separate columns

Really stumped on this one. I'm trying to figure out how i can get my SQL query shown below to do a count of null and not null aircraft ID's with a table of results that has two count columns, one for NULL aircraft IDs and another for Not NULL aircraft IDs and is grouped by operator, so it looks something like this:
SELECT DISTINCT org.organization "operator",
ah.aircraft_registration_country "country",
ah.aircraft_registration_region "region",
acl.aircraft_master_series "aircraft type",
ah.publish_date "publish date",
f.aircraft_id "aircraft_id"
FROM ((((("flights"."tracked_utilization" f
left join "pond_dataops_analysis"."latest_aircraft" a
ON ( a.aircraft_id = f.aircraft_id ))
left join fleets.aircraft_all_history_latest ah
ON ( ( ( ah.aircraft_id = f.aircraft_id )
AND ( Coalesce(f.actual_runway_departure_time_local,
actual_gate_departure_time_local,
published_gate_departure_time_local) >=
ah.start_event_date ) )
AND ( Coalesce(f.actual_runway_departure_time_local,
actual_gate_departure_time_local,
published_gate_departure_time_local) <
ah.end_event_date ) ))
left join fleets.organizations_latest org
ON ( org.organization_id = ah.operator_organization_id )))
left join fleets.aircraft_usage_history_latest ash
ON ( ( ( ( ash.aircraft_id = f.aircraft_id )
AND ( start_event_date >= ash.usage_start_date ) )
AND ( start_event_date < ash.usage_end_date ) )
AND ( aircraft_usage_classification = 'Primary' ) )
left join fleets.aircraft_configuration_history_latest accl
ON ash.aircraft_id = accl.aircraft_id
left join fleets.aircraft_configurations_latest acl
ON accl.aircraft_configuration_id = acl.aircraft_configuration_id
)
WHERE (((( f.flight_departure_date > ( "Now"() - interval '90' day ) ))))
Not sure how to do a 'count/group by' so that the query can show what i'm after.
Regards,
Mark
Something like this:
select
x, y, z,
sum( case when aircraft_id is null then 1 else 0 end ) as null_cnt,
sum( case when aircraft_id is null then 0 else 1 end ) as notnull_cnt
from
(inline subquery)
group by
x, y, z
FWIW, you don't need all those parentheses in your query, they are unnecessary and more confusing than helpful. They do have their place in some cases, especially when dealing with "OR" conditions, but for this query they are completely superfluous:
FROM
"flights"."tracked_utilization" f
left join "pond_dataops_analysis"."latest_aircraft" a
ON a.aircraft_id = f.aircraft_id
left join fleets.aircraft_all_history_latest ah
ON ah.aircraft_id = f.aircraft_id
AND Coalesce(f.actual_runway_departure_time_local, actual_gate_departure_time_local, published_gate_departure_time_local) >= ah.start_event_date
AND Coalesce(f.actual_runway_departure_time_local, actual_gate_departure_time_local, published_gate_departure_time_local) < ah.end_event_date
left join fleets.organizations_latest org
ON org.organization_id = ah.operator_organization_id
left join fleets.aircraft_usage_history_latest ash
ON ash.aircraft_id = f.aircraft_id
AND start_event_date >= ash.usage_start_date
AND start_event_date < ash.usage_end_date
AND aircraft_usage_classification = 'Primary'
left join fleets.aircraft_configuration_history_latest accl
ON ash.aircraft_id = accl.aircraft_id
left join fleets.aircraft_configurations_latest acl
ON accl.aircraft_configuration_id = acl.aircraft_configuration_id
WHERE
f.flight_departure_date > "Now"() - interval '90' day

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

Count with row_number function SQL CTE

I have the below CTEs that work perfectly, but I want to count the "cl.memb_dim_id" by "cl.post_date" but I am not sure how to do that? When adding in the count function I get an error that highlights the ' row number' so I am assuming I cant have both order and group together ????
WITH
DATES AS
(
select to_date('01-jan-2017') as startdate,to_date('02-jan-2017') as enddate
from dual
),
Claims as (select distinct
cl.memb_dim_id,
row_number () over (partition by cl.Claim_number order by cl.post_date desc) as uniquerow,
cl.Claim_number,
cl.post_date,
ct.claim_type,
ap.claim_status_desc,
dc.company_desc,
dff.io_flag_desc,
pr.product_desc,
cl.prov_dim_id,
cl.prov_type_dim_id
from dw.fact_claim cl
inner join dates d
on 1=1
and cl.post_date >= d.startdate
and cl.post_date <= d.enddate
and cl.provider_par_dim_id in ('2')
and cl.processing_status_dim_id = '1'
and cl.company_dim_id in ('581','585','586','589','590','591','588','592','594','601','602','603','606','596','598','597','579','599','578','577','573','574','576','575')
left join dw.DIM_CLAIM_STATUS ap
on cl.claim_status_dim_id = ap.claim_status_dim_id
left join dw.dim_claim_type ct
on cl.claim_type_dim_id = ct.claim_type_dim_id
and cl.claim_type_dim_id in ('1','2','6','7')
left join dw.DIM_COMPANY dc
on cl.company_dim_id = dc.company_dim_id
left join dw.DIM_IO_FLAG dff
on cl.io_flag_dim_id = dff.io_flag_dim_id
left join dw.dim_product pr
on cl.product_dim_id = pr.product_dim_id
)
Select * from claims where uniquerow ='1'
First, does this work?
count(cl.memb_dim_id) over (partition by cl.Claim_number, cl.post_date) as cnt,
Second, it is strange to be using analytic functions with select distinct.

not able to select a column outside left join

I am working with the below query
SELECT * FROM
(SELECT DISTINCT
a.Number
,a.Description
,ISNULL(temp.Quantity,0) Quantity
,LastReceived
,LastIssued
FROM Article a
LEFT JOIN (
select ss.ArticleId
, ss.Quantity
, max(lastreceiveddate) as LastReceived
, max(lastissueddate) as LastIssued
from StockSummary ss
where ss.UnitId = 8
group by ss.ArticleId, ss.StockQuantity
having (MAX(ss.LastReceivedDate) < '2014-09-01' or MAX(ss.LastReceivedDate) is NULL)
AND (MAX(ss.LastIssuedDate) < '2014-09-01' or MAX(ss.LastIssuedDate) is NULL)
) temp on a.Id = temp.ArticleId
WHERE a.UnitId = 8
) main
ORDER BY main.Number
What i want to achieve is to select the articles only with the MAX(ss.LastReceivedDate) and MAX(ss.LastIssuedDate) condition in the Left join query and then do the Quantity Select in the main query.
Note: the quantity column can be 0 or NULL.
Kindly help

Using MAX for date but adding column to group on 'breaks' the query - sub query?

I Have a table which holds date but I need to know the latest date where a condition is true per location, only issue is once I add a column called 'notes' it breaks the query and returns too many rows, current query is ...
SELECT
Location,
MAX(date) AS date,
type,
notes
FROM NotesTable a
INNER JOIN Location b on a.LocationID = b.LocationID
INNER JOIN Type c on a.typeid = c.typeid
WHERE typeid <> 8
GROUP BY Location, type, notes
If I comment out the notes column then it works fine but as soon as I add that to the grouping it then returns more rows than required.
Have tried using a subquery but still cant get it working, subquery below
SELECT
r.location,
r.date,
r.type,
t.notes
FROM (SELECT Location, MAX(date), type
FROM NotesTable a INNER JOIN Location b on a.LocationID = b.LocationID
INNER JOIN Type c on a.typeid = c.typeid
WHERE typeid <> 8
GROUP BY location,type
) r
INNER JOIN NotesTable t ON t.date = r.date
Anyone got any other suggestions?
select * from
(
SELECT Location,Date, Type, Notes, Row_Number() Over (Partition By Location, Type order by date desc) RN
FROM
NotesTable a
INNER JOIN Location b on a.LocationID = b.LocationID
INNER JOIN Type c on a.typeid = c.typeid
WHERE typeid <> 8
) v
WHERE rn = 1
Your query is almost correct, you need to add this additional condition in ON clause
AND
t.location = r.location AND
t.type = r.type
full query,
SELECT r.location
, r.DATE
, r.type
, t.notes
FROM (
SELECT Location
, MAX(DATE) maxDate
, type
FROM NotesTable a
INNER JOIN Location b
ON a.LocationID = b.LocationID
INNER JOIN Type c
ON a.typeid = c.typeid
WHERE typeid <> 8
GROUP BY location
, type
) r
INNER JOIN NotesTable t
ON t.DATE = r.maxDate AND
t.location = r.location AND
t.type = r.type