IIF with ISNULL? - sql

SELECT first_name, last_name
(SELECT ISNULL(IIF(getdate() between vacation_start and vacation_end, 1, 0),0) from vacatoin_request where mat_emp = W.mat_emp) as is_on_vacation,
(SELECT ISNULL(IIF(getdate() between mission_start and mission_end, 1, 0),0) from mission_order where mat_emp = W.mat_emp) as is_on_mission
FROM
workers W
IIF is working fine but when I add ISNULL, It's still returning null If that worker have no vacation requests or mission orders in the other tables.

The problem is the select returns NULL so ISNULL needs to be outside the select
SELECT first_name, last_name
ISNULL((SELECT TOP 1 IIF(getdate() between vacation_start and vacation_end, 1, 0) from vacatoin_request where mat_emp = W.mat_emp),0) as is_on_vacation,
ISNULL((SELECT TOP 1 IIF(getdate() between mission_start and mission_end, 1, 0) from mission_order where mat_emp = W.mat_emp),0) as is_on_mission
FROM
workers W

SELECT
first_name, last_name
CASE WHEN v.mat_emp IS NOT NULL THEN 1 ELSE 0 END as is_on_vacation
CASE WHEN m.mat_emp IS NOT NULL THEN 1 ELSE 0 END as is_on_mission
FROM
workers W
LEFT JOIN
vacatoin_request v
ON
v.mat_emp = W.mat_emp AND
getdate() between v.vacation_start and v.vacation_end
LEFT JOIN
mission_order m
ON
m.mat_emp = W.mat_emp AND
getdate() between m.mission_start and m.mission_end

SELECT first_name, last_name
(SELECT COUNT(DISTINCT v.mat_empt) from vacatoin_request v where v.mat_emp = W.mat_emp and getdate() between vacation_start and vacation_end) as is_on_vacation,
(SELECT COUNT(DISTINCT m.mat_emp) from mission_order m where m.mat_emp = W.mat_emp and getdate() between mission_start and mission_end) as is_on_mission
FROM
workers W

Related

how to use case with group by?

the query works well but when iam adding group by it gives me [Error] ORA-01427 here is the main query
SELECT DISTINCT Contract_number,
area_number,
area_name,
ADVANCE_PAY,
Postponed_Amount,
extract_number,
total
FROM (SELECT xxr.Contract_num Contract_number,
xxr.p_area_no area_number,
xxr.p_area_name area_name,
xxr.ADVANCE_PAY ADVANCE_PAY,
xxr.DEFERRED_BOOST Postponed_Amount,
xxr.release_num extract_number,
and here is the case statement :
(SELECT DISTINCT
CASE
WHEN :p_item_code IS NOT NULL
THEN
TOTAL_AMOUNT
WHEN :p_item_code IS NULL
THEN
( (SELECT NVL (SUM (TOTAL_AMOUNT), 0)
FROM XXEXTRACT.XXNATGAS_REALSES_LINES
WHERE XXEXTRACT.XXNATGAS_REALSES.release_id =
XXEXTRACT.XXNATGAS_REALSES_LINES.release_id))
ELSE
NULL
END
FROM XXEXTRACT.XXNATGAS_REALSES_LINES xxrl,
XXEXTRACT.XXNATGAS_REALSES
WHERE 1 = 1
AND xxrl.release_id =
XXEXTRACT.XXNATGAS_REALSES.release_id)
AS total
and here is the from part :
FROM XXEXTRACT.XXNATGAS_REALSES_LINES xxrl,
XXEXTRACT.XXNATGAS_REALSES xxr
WHERE 1 = 1
AND xxrl.release_id = xxr.release_id
AND xxr.release_date >= NVL (:p_date_from, xxr.release_date)
AND xxr.release_date <= NVL (:p_date_to, xxr.release_date)
AND xxr.Contract_num = NVL (:p_cont_num, xxr.Contract_num)
AND xxr.vendor_id = NVL (:p_ven_id, xxr.vendor_id)
AND xxr.vendor_site_id = NVL (:p_site_id, xxr.vendor_site_id)
)
and here is the group by :
GROUP BY Contract_number,
area_number,
area_name,
ADVANCE_PAY,
Postponed_Amount,
extract_number,
total;
these is the full query so please any help
For sure I couldn't understand very well your query. You could improve your post for next time.
As answer, I think you should encapsulate your select statment and group by using your select as subquery. It is not the best approach but it may works fine.
select *
from (
select distinct Contract_number
,area_number
,area_name
,ADVANCE_PAY
,Postponed_Amount
,extract_number
,total
from (
select xxr.Contract_num Contract_number
,xxr.p_area_no area_number
,xxr.p_area_name area_name
,xxr.ADVANCE_PAY ADVANCE_PAY
,xxr.DEFERRED_BOOST Postponed_Amount
,xxr.release_num extract_number
,(
select distinct case
when :p_item_code is not null
then TOTAL_AMOUNT
when :p_item_code is null
then (
(
select NVL(SUM(TOTAL_AMOUNT), 0)
from XXEXTRACT.XXNATGAS_REALSES_LINES
where XXEXTRACT.XXNATGAS_REALSES.release_id = XXEXTRACT.XXNATGAS_REALSES_LINES.release_id
)
)
else null
end
from XXEXTRACT.XXNATGAS_REALSES_LINES xxrl
,XXEXTRACT.XXNATGAS_REALSES
where 1 = 1
and xxrl.release_id = XXEXTRACT.XXNATGAS_REALSES.release_id
) as total
from XXEXTRACT.XXNATGAS_REALSES_LINES xxrl
,XXEXTRACT.XXNATGAS_REALSES xxr
where 1 = 1
and xxrl.release_id = xxr.release_id
and xxr.release_date >= NVL(:p_date_from, xxr.release_date)
and xxr.release_date <= NVL(:p_date_to, xxr.release_date)
and xxr.Contract_num = NVL(:p_cont_num, xxr.Contract_num)
and xxr.vendor_id = NVL(:p_ven_id, xxr.vendor_id)
and xxr.vendor_site_id = NVL(:p_site_id, xxr.vendor_site_id)
)
) TBL1
group by TBL1.Contract_number
,TBL1.area_number
,TBL1.area_name
,TBL1.ADVANCE_PAY
,TBL1.Postponed_Amount
,TBL1.extract_number
,TBL1.total;

Distinct keyword not fetching results in Oracle

I have the following query where I unique records for patient_id, meaning patient_id should not be duplicate. Each time I try executing the query, seems like the DB hangs or it takes hours to execute, I'm not sure. I need my records to load quickly. Any quick resolution will be highly appreciated.
SELECT DISTINCT a.patient_id,
a.study_id,
a.procstep_id,
a.formdata_seq,
0,
(SELECT MAX(audit_id)
FROM audit_info
WHERE patient_id =a.patient_id
AND study_id = a.study_id
AND procstep_id = a.procstep_id
AND formdata_seq = a.formdata_seq
) AS data_session_id
FROM frm_rg_ps_rg a,
PATIENT_STUDY_STEP pss
WHERE ((SELECT COUNT(*)
FROM frm_rg_ps_rg b
WHERE a.patient_id = b.patient_id
AND a.formdata_seq = b.formdata_seq
AND a.psdate IS NOT NULL
AND b.psdate IS NOT NULL
AND a.psresult IS NOT NULL
AND b.psresult IS NOT NULL) = 1)
OR NOT EXISTS
(SELECT *
FROM frm_rg_ps_rg c
WHERE a.psdate IS NOT NULL
AND c.psdate IS NOT NULL
AND a.psresult IS NOT NULL
AND c.psresult IS NOT NULL
AND a.patient_id = c.patient_id
AND a.formdata_seq = c.formdata_seq
AND a.elemdata_seq! =c.elemdata_seq
AND a.psresult != c.psresult
AND ((SELECT (a.psdate - c.psdate) FROM dual)>=7
OR (SELECT (a.psdate - c.psdate) FROM dual) <=-7)
)
AND a.psresult IS NOT NULL
AND a.psdate IS NOT NULL;
For start, you have a cartesian product with PATIENT_STUDY_STEP (pss).
It is not connected to anything.
select *
from (select t.*
,count (*) over (partition by patient_id) as cnt
from frm_rg_ps_rg t
) t
where cnt = 1
;

How to add a count/sum and group by in a CTE

Just a question on displaying a row on flight level and displaying a count on how many crew members on that flight.
I want to change the output so it will only display a single record at flight level and it will display two additional columns. One column (cabincrew) is the count of crew members that have the 'CREWTYPE' = 'F' and the other column (cockpitcrew) is the count of crew members that have the `'CREWTYPE' = 'C'.
So the query result should look like:
Flight DepartureDate DepartureAirport CREWBASE CockpitCrew CabinCrew
LS361 2016-05-19 BFS BFS 0 3
Can I have a little help tweaking the below query please:
WITH CTE AS (
SELECT cd.*, c.*, l.Carrier, l.FlightNumber, l.Suffix, l.ScheduledDepartureDate, l.ScheduledDepartureAirport
FROM
(SELECT *, ROW_NUMBER() OVER(PARTITION BY LegKey ORDER BY UpdateID DESC) AS RowNumber FROM Data.Crew) c
INNER JOIN
Data.CrewDetail cd
ON c.UpdateID = cd.CrewUpdateID
AND cd.IsPassive = 0
AND RowNumber = 1
INNER JOIN
Data.Leg l
ON c.LegKey = l.LegKey
)
SELECT
sac.Airline + CAST(sac.FlightNumber AS VARCHAR) + sac.Suffix AS Flight
, sac.DepartureDate
, sac.DepartureAirport
, sac.CREWBASE
, sac.CREWTYPE
, sac.EMPNO
, sac.FIRSTNAME
, sac.LASTNAME
, sac.SEX
FROM
Staging.SabreAssignedCrew sac
LEFT JOIN CTE cte
ON sac.Airline + CAST(sac.FlightNumber AS VARCHAR) + sac.Suffix = cte.Carrier + CAST(cte.FlightNumber AS VARCHAR) + cte.Suffix
AND sac.DepartureDate = cte.ScheduledDepartureDate
PLEASE TRY THIS.
SELECT Flight,
DepartureDate,
DepartureAirport,
CREWBASE,
SUM(CASE WHEN CREWTYPE = 'F' THEN 1 ELSE 0 END) AS CabinCrew ,
SUM(CASE WHEN CREWTYPE = 'C' THEN 1 ELSE 0 END) AS CockpitCrew
FROM #Table
GROUP BY Flight, DepartureDate, DepartureAirport, CREWBASE
Please Try This:
select Flight, DepartureDate, DepartureAirport,CREWBASE,
count(case when CREWTYPE='F' then 1 end ) as CabinCrew,count(case when CREWTYPE='C' then 1 end ) as CockpitCrew
from Staging.SabreAssignedCrew
group by Flight, DepartureDate, DepartureAirport,CREWBASE

SQL Server : CTE going a level back in the where clause

I would like to set a limit to a recursive query. But I don't want to lose the last entry on which i limited the recursion.
Right now the query looks like this:
WITH MyCTE (EmployeeID, FirstName, LastName, ManagerID, level, SPECIAL)
AS (
SELECT a.EmployeeID, a.FirstName, a.LastName, a.ManagerID, 0 as Level
FROM MyEmployees as a
WHERE ManagerID IS NULL
UNION ALL
SELECT b.EmployeeID, b.FirstName, b.LastName, b.ManagerID, level + 1
FROM MyEmployees as b
INNER JOIN MyCTE ON b.ManagerID = MyCTE.EmployeeID
WHERE b.ManagerID IS NOT NULL and b.LastName != 'Welcker'
)
SELECT *
FROM MyCTE
OPTION (MAXRECURSION 25)
And it gets limited by the Manager Welcker, the result looks like this:
EmployeeID; FirstName; LastName; ManagerID; level
1 Ken Sánchez NULL 0
What I want is to have the employee 'Welcker' included. The problem is I only have the name of the last person I need to have on my list. There are some entries below in the command structure but I don't know them and I don't want to see them.
Here's a example of how I imagine the result of my query to look.
EmployeeID FirstName LastName ManagerID level
1 Ken Sánchez NULL 0
273 Brian Welcker 1 1
Any help would be very much appreciated
WITH MyCTE (EmployeeID, FirstName, LastName, ManagerID, level, NotMatched)
AS (
SELECT a.EmployeeID, a.FirstName, a.LastName, a.ManagerID, 0 as Level, 0 AS NotMatched
FROM MyEmployees as a
WHERE ManagerID IS NULL
UNION ALL
SELECT b.EmployeeID, b.FirstName, b.LastName, b.ManagerID, level + 1,
CASE WHEN (MyCTE.LastName = 'Welcker' AND MyCTE.level = 1) THEN 1 ELSE MyCTE.NotMatched END
FROM MyEmployees as b
INNER JOIN MyCTE ON b.ManagerID = MyCTE.EmployeeID
)
SELECT *
FROM MyCTE
WHERE NotMatched != 1
Can you just change that one line to b.LastName = 'Welcker'?
select distinct
t.b_eid as empId,
t.b_name as name,
case t.b_mid when 0 then null else t.b_mid end as managerId
--convert(varchar,t.b_eid) + ', ' +
--t.b_name + ', ' +
--case t.b_mid when '0' then 'null' else convert(varchar,t.b_mid) end
--as bvals
from(
select
coalesce(a.mid, 0) as a_mid,
a.eid as a_eid,
a.name as a_name,
coalesce(b.mid, 0) as b_mid,
b.eid as b_eid,
b.name as b_name
from
(values(null,1,'adam'),(null,2,'barb'),(201,3,'chris')) as a(mid,eid,name) cross join
(values(null,1,'adam'),(null,2,'barb'),(201,3,'chris')) as b(mid,eid,name)
) as t
where (t.a_mid = t.b_eid or t.a_mid = 0 or t.b_mid = 0) and t.a_name != 'chris'

SQL: How to join correctly in order to calculate contact statistics from call log

The call log has the following columns:
CallingParty, CalledParty, Duration, EventTime
and the example data is the following:
X, a, 10, 10:20
X, b, 12, 10:34
X, c, 8, 12:08
a, X, 22, 12:45
X, a, 10, 13:55
d, X, 30, 15:01
What I would like to do is to calculate the statistics for each contact (how many times did the user X call the contact, what was the sum of outgoing calls duration, how many times did the contact call user X, and what was the sum of incoming calls duration). Actually I am trying to mine the data from the call log of user X.
The statistics for the example above would be the following:
contactName, incomingCallsCount, IncomingCallsDuration, OutgoingCallsCount, OutgoingCallsDuration
a, 1, 10, 2, 20
b, 0, 0, 1, 12
c, 0, 0, 1, 8
d, 1, 30, 0, 0
I tryed the following query with different joins () but couldn't fet the right result
SELECT t1.CallingParty AS Contact, t1.CallingPartyCount, t1.CallingPartyDuration, t2.CalledPartyCount, t2.CalledPartyDuration FROM
(SELECT e.CallingParty, COUNT(*) AS CallingPartyCount, SUM(CAST(REPLACE(e.Duration, 'NULL', '0') AS int)) AS CallingPartyDuration FROM Events e WHERE Duration <> 'NULL' GROUP BY e.CallingParty) t1
<JOIN>
(SELECT e.CalledParty, COUNT(*) AS CalledPartyCount, SUM(CAST(REPLACE(e.Duration, 'NULL', '0') AS int)) AS CalledPartyDuration FROM Events e WHERE Duration <> 'NULL' GROUP BY e.calledParty) t2
ON t1.CallingParty = t2.CalledParty
Does anyone know what would be the right query in order to get the correct statistics?
Thank You!
Try this:
WITH qry AS
(
SELECT a.*,
CASE CallingParty
WHEN 'X' THEN CalledParty
ELSE CallingParty
END AS contactName
FROM CallLog a
WHERE ( CallingParty = 'X' OR CalledParty = 'X')
)
SELECT contactName,
SUM( CASE CallingParty WHEN 'X' 1 ELSE 0 END) AS incomingCallsCount,
SUM( CASE CallingParty WHEN 'X' Duration ELSE 0 END) AS incomingDurationCount
SUM( CASE CallingParty WHEN 'X' 0 ELSE 1 END) AS outgoingCallsCount,
SUM( CASE CallingParty WHEN 'X' 0 ELSE Duration END) AS outgoingDurationCount
FROM qry
GROUP BY contactName
You shouldn't be joining to begin with, it sounds more like a simple group by with sum and count.
SELECT CallingParty, CalledParty, SUM(Duration), COUNT(*)
FROM table
GROUP BY CallingParty, CalledParty
Now, you also need a set of all the users involved (a,b,c and d), that can be computed by using a UNION if you don't have this somewhere else.
SELECT CallingParty FROM table
UNION
SELECT CalledParty FROM table
Then you just put these together using CTEs.
WITH outgoing AS (
SELECT CallingParty, CalledParty, SUM(Duration), COUNT(*)
FROM table
GROUP BY CallingParty, CalledParty
), incoming AS (
SELECT CalledParty, CallingParty, SUM(Duration), COUNT(*)
FROM table
GROUP BY CalledParty, CallingParty
), users AS (
SELECT CallingParty AS UserID FROM table
UNION
SELECT CalledParty AS UserID FROM table
)
SELECT *
FROM users
LEFT OUTER JOIN outgoing ON outgoing.CallingParty = UserID
LEFT OUTER JOIN incoming ON incoming.CalledParty = UserID
That's should do it!
It's a lot simpler than that:
SELECT contact,
sum(t1.CallingParty is not null) as CallingPartyCount,
sum(t1.CallingPartyDuration) as CallingPartyDuration,
sum(t2.CalledPartyCount is not null) as CalledPartyCount,
sum(t2.CalledPartyDuration) as CalledPartyDuration
FROM
(select distinct CallingParty as contact from Event) e
left join Event t1 on t1.CallingParty = contact
left join Event t2 on t2.CalledParty = contact
I would implement it like this:
WITH EventsForX AS (
SELECT
isIncoming = CASE CalledParty WHEN #X THEN 1 ELSE 0 END,
contactName = CASE CalledParty WHEN #X THEN CallingParty ELSE CalledParty END,
Duration,
FROM Events
WHERE CallingParty = #X
OR CalledParty = #X
)
SELECT
contactName,
incomingCallsCount = SUM(isIncoming),
incomingCallsDuration = SUM(isIncoming * Duration),
outcomingCallsCount = SUM(1 - isIncoming),
outcomingCallsDuration = SUM((1 - isIncoming) * Duration)
FROM EventsForX
GROUP BY contactName