Spool space error
I ran the query and I get no more spool space in ID error. When I remove the 2 select statements (above the from statement), it runs fine. Need help optimizing the query please.
select NOT_FILETM_LOC_DTTM as documented_date, HNO_INFO.pat_enc_csn_id, AUTHOR_USER_ID, clarity_emp.name as md,patient.pat_id,hno_note_text.note_text, pat_mrn_id, cast(NOT_FILETM_LOC_DTTM as date) - cast( patient.birth_date as date) year (4) as age,
(select department_name from clarity_dep, clarity_adt where clarity_adt.department_id = dep.department_id and event_id =
(select max(event_id) from clarity_adt adt where pat_enc_hsp.pat_enc_csn_id = adt.pat_enc_csn_id and adt.EVENT_SUBTYPE_C <> 2 and adt.event_type_c<>6 and adt.effective_time <= NOT_FILETM_LOC_DTTM) ) as unit
from HNO_INFO, hno_note_text, NOTE_ENC_INFO, clarity_emp, patient, pat_enc_hsp
where OTE_ENC_INFO.note_id = HNO_INFO.note_id
and hno_note_text.note_id = HNO_INFO.note_id
and hno_note_text.note_text like ('%Procedural Sedation Stop Time:%')
and (hno_note_text.note_text like ('%PICC%') or hno_note_text.note_text like ('%Lumbar Puncture%'))
and emp.user_id = AUTHOR_USER_ID
and patient.pat_id = HNO_INFO.pat_id
and pat_enc_hsp.pat_enc_csn_id = HNO_INFO.pat_enc_csn_id
and cast(documented_date as date) >= '2018-01-01'
qualify row_number() over (partition by HNO_INFO.pat_enc_csn_id order by documented_date )=1
Okay, let's try this:
select
NOT_FILETM_LOC_DTTM as documented_date
, HNO_INFO.pat_enc_csn_id,
AUTHOR_USER_ID, emp."NAME" as md,patient.pat_id,hno_note_text.note_text, pat_mrn_id
, cast(NOT_FILETM_LOC_DTTM as date) - cast( patient.birth_date as date) year (4) as age
, department_name unit
, adt.event_id
from HNO_INFO
, hno_note_text
, NOTE_ENC_INFO
, clarity_emp emp
, patient
, pat_enc_hsp
,clarity_dep
--, clarity_adt
,(select max(event_id) event_id, adt.pat_enc_csn_id, department_id, effective_time from clarity_adt adt
where adt.EVENT_SUBTYPE_C <> 2 and adt.event_type_c<>6
group by adt.pat_enc_csn_id, department_id, effective_time
) adt
where
NOTE_ENC_INFO.note_id = HNO_INFO.note_id
and adt.department_id = clarity_dep.department_id
and pat_enc_hsp.pat_enc_csn_id = adt.pat_enc_csn_id
and adt.effective_time <= NOT_FILETM_LOC_DTTM
and hno_note_text.note_id = HNO_INFO.note_id
and hno_note_text.note_text like ('%Procedural Sedation Stop Time:%')
and (hno_note_text.note_text like ('%PICC%') or hno_note_text.note_text like ('%Lumbar Puncture%'))
and emp.user_id = AUTHOR_USER_ID
and patient.pat_id = HNO_INFO.pat_id
and pat_enc_hsp.pat_enc_csn_id = HNO_INFO.pat_enc_csn_id
and cast(documented_date as date) >= '2018-01-01'
qualify row_number() over (partition by HNO_INFO.pat_enc_csn_id order by documented_date )=1
;
Related
first punch as in time,
second punch as out time
if possible avoid duplicate punch on same time within a minute
I need to get all in time ,outtime in a row with total hours
like below any format.
I tried below query but can't get my expected output
WITH Level1
AS (
SELECT A.emp_reader_id,
DT
,A.EventCatId
,A.Belongs_to
,ROW_NUMBER() OVER ( PARTITION BY A.Belongs_to,A.emp_reader_id ORDER BY DT ) AS RowNum
FROM dbo.trnevents A
)
,
LEVEL2
AS (-- find the last and next event type for each row
SELECT A.emp_reader_id,A.DT , A.EventCatId ,COALESCE(LastVal.EventCatId, 10) AS LastEvent,
COALESCE(NextVal.EventCatId, 10) AS NextEvent ,A.Belongs_to
FROM Level1 A
LEFT JOIN Level1 LastVal
ON A.emp_reader_id = LastVal.emp_reader_id and A.Belongs_to=LastVal.Belongs_to
AND A.RowNum - 1 = LastVal.RowNum
LEFT JOIN Level1 NextVal
ON A.emp_reader_id = NextVal.emp_reader_id and A.Belongs_to=NextVal.Belongs_to
AND A.RowNum + 1 = NextVal.RowNum
)
select * from level2 where emp_reader_id=92 order by dt desc
Expected output:
Try this below script. I considered all DT with Sam Minutes as single entry for the calculation.
WITH CTE AS
(
SELECT MAX(emp_reader_id) emp_reader_id,
CAST(DT AS DATE) Date_for_Group,
LEFT(CAST(DT AS VARCHAR),16) Time_For_Group,
ROW_NUMBER() OVER(PARTITION BY CAST(DT AS DATE) ORDER BY LEFT(CAST(DT AS VARCHAR),16)) RN,
CASE
WHEN ROW_NUMBER() OVER(PARTITION BY CAST(DT AS DATE) ORDER BY LEFT(CAST(DT AS VARCHAR),16))%2 = 0 THEN 'OUT'
ELSE 'IN'
END In_Out
FROM your_table
GROUP BY CAST(DT AS DATE),LEFT(CAST(DT AS VARCHAR),16)
)
SELECT A.emp_reader_id,A.Date_for_Group,
SUM(DATEDIFF(Minute,CAST(A.Time_For_Group AS DATETIME),CAST(B.Time_For_Group AS DATETIME)))/60 Hr,
SUM(DATEDIFF(Minute,CAST(A.Time_For_Group AS DATETIME),CAST(B.Time_For_Group AS DATETIME)))%60 Min
FROM CTE A
INNER JOIN CTE B
ON A.emp_reader_id = B.emp_reader_id
AND A.RN = B.RN -1
AND A.Date_for_Group = B.Date_for_Group
WHERE A.In_Out = 'IN'
GROUP BY A.emp_reader_id,A.Date_for_Group
first assign rownumber to datetime column then start the same result set with rownumber+1
Then Inner join them on rownumbers. After that select min an max from timein and out columns and group by on date to get total workhours of that day. hope it helps.
select empid
,date
,min(timein) as timein,max (timeout) timeout,convert(nvarchar(20),datediff(hh,min (timein),max(timeout))%24)
+':'+
convert(nvarchar(20),datediff(mi,min (timein),max(timeout))%60) as totalhrs
from(
Select a.empid,cast(a.dt as date) date,b.dt as timein,a.dt as timeout from(
SELECT DT
,[empid]
, id
,row_number() over(order by dt) as inn
FROM [test1].[dbo].[Table_2]
)a
inner join(
SELECT distinct DT
,[empid]
, id
,rank() over(order by dt)+1 as out
FROM [test1].[dbo].[Table_2])b
on FORMAT(a.dt,'hh:mm') <> FORMAT(b.dt,'hh:mm')
and cast(a.dt as date)=cast(b.dt as date)
and a.inn=b.out)b
group by b.empid,b.date
I need to be able to get rid of one of the workdate and one of the sr_name columns but I can't figure out how to.
I'm getting the query returned like this:
Query
I'm also getting this error message when entered into tableau:
The column 'sr_name' was specified multiple times for 'Custom SQL Query'.
Below is the code I have. If I remove a sr_name from either subquery there will be an error in the join clause.
select *
from
(
select s.sr_name, cast(punchdatetime as date) as workdate,
((datediff(second, min(case when p.InOut = 1 then punchdatetime end),
max(case when p.InOut = 0 then punchdatetime end))/3600) - .5) as
hoursworked
from PunchClock p join ServiceReps s on p.ServRepID = s.ServRepID
where punchyear >= 2019
group by s.sr_name, cast(punchdatetime as date)
) v
join
(
select sr_name, t.*,
calls = (select count(*) from CRM_Correspondence cr where
cast(cr.DateCreated as date) = workdate and StatusType like '%call%' and
cr.ServRepID = t.servrepid),
reaches = (select count(*) from CRM_Correspondence cr where
cast(cr.DateCreated as date) = workdate and (StatusType = 'call reached'
or StatusType like '%SCHEDULE%') and cr.ServRepID = t.servrepid),
books = (select count(*) from os_appointments o where cast(o.DateCreated
as date) = workdate and isnull(o.confirmedby, o.booked_by) =
t.servrepid),
attends = (select count(*) from os_appointments o where
cast(o.DateCreated as date) = workdate and isnull(o.confirmedby,
o.booked_by) = t.servrepid and o.appointmentStatus = 'attended')
from
(
select cast(cor.datecreated as date) workdate, cor.ServRepID
from CRM_Correspondence cor
where cor.datecreated > '2019-01-01'
group by cast(cor.datecreated as date), cor.servrepid
) t
join ServiceReps sr on t.ServRepID = sr.ServRepID
) u on v.sr_name = u.sr_name and v.workdate = u.workdate
I need the same results just without the duplicate column so I can enter the query into tableau.
This is challenging because you have so many subqueries here. This could be refactored to use a single query which is what I would do. But using the existing query you could do something along these lines.
I had to format this very differently so I could isolate each piece.
select v.sr_name
, v.workdate
, v.hoursworked
, u.ServRepID
, u.calls
, u.reaches
, u.books
, u.attends
from
(
select s.sr_name
, cast(punchdatetime as date) as workdate
, ((datediff(second, min(case when p.InOut = 1 then punchdatetime end), max(case when p.InOut = 0 then punchdatetime end))/3600) - .5) as hoursworked
from PunchClock p
join ServiceReps s on p.ServRepID = s.ServRepID
where punchyear >= 2019
group by s.sr_name
, cast(punchdatetime as date)
) v
join
(
select sr_name
, t.*
, calls =
(
select count(*)
from CRM_Correspondence cr
where cast(cr.DateCreated as date) = workdate
and StatusType like '%call%'
and cr.ServRepID = t.servrepid
)
, reaches =
(
select count(*)
from CRM_Correspondence cr
where cast(cr.DateCreated as date) = workdate
and (StatusType = 'call reached' or StatusType like '%SCHEDULE%')
and cr.ServRepID = t.servrepid
)
, books =
(
select count(*)
from os_appointments o
where cast(o.DateCreated as date) = workdate and isnull(o.confirmedby, o.booked_by) = t.servrepid
)
, attends =
(
select count(*)
from os_appointments o
where cast(o.DateCreated as date) = workdate
and isnull(o.confirmedby, o.booked_by) = t.servrepid
and o.appointmentStatus = 'attended'
)
from
(
select cast(cor.datecreated as date) workdate
, cor.ServRepID
from CRM_Correspondence cor
where cor.datecreated > '2019-01-01'
group by cast(cor.datecreated as date)
, cor.servrepid
) t
join ServiceReps sr on t.ServRepID = sr.ServRepID
) u on v.sr_name = u.sr_name
and v.workdate = u.workdate
I am trying to get minimum and maximum date for area 12. I do not know how to use where clause inside a query.
SELECT A1.*, Ticket_ID,
min(StartDate) OVER(PARTITION BY Ticket_ID) AS Min_StartDate,
MAX(EndDate) OVER(PARTITION BY Ticket_ID) AS Max_EndDate
WHERE area = '12'
FROM (SELECT T1.Ticket_ID, T1.StartDate,T1.StartDate, t2.title, t1.area,T2.Ticket_TYPE
FROM Ticket1 t1
LEFT JOIN Ticket2 t2 on t1.Ticket_ID = t2.Ticket_ID
) A1
WHERE Ticket_TYPE = 1 AND StartDate <= '9/30/2017'
AND (EndDate >= '10/01/2017' OR EndDate IS NULL)
ORDER BY Ticket_ID
Try to run it as:
SELECT A1.*, A1.Ticket_ID,
min(StartDate) OVER(PARTITION BY Ticket_ID) AS Min_StartDate,
MAX(EndDate) OVER(PARTITION BY Ticket_ID) AS Max_EndDate
FROM (SELECT T1.Ticket_ID, T1.StartDate,T1.EndDate, t2.title, t1.area,T2.Ticket_TYPE
FROM Ticket1 t1
LEFT JOIN Ticket2 t2 on t1.Ticket_ID = t2.Ticket_ID
WHERE t2.Ticket_TYPE = 1 AND t1.StartDate <= '9/30/2017'
AND (t1.EndDate >= '10/01/2017' OR t1.EndDate IS NULL)
AND t1.area = '12'
) A1
ORDER BY A1.Ticket_ID
*You have a typo of specifying StartDate twice, corrected as EndDate in subquery.
The SQL below is written to return 'open orders'. This was written in a way I could understand but now I would like to try and optimize this and reduce the amount of code.
The SQL below gives me the desired outcome I'm looking for however, I would like to shorten the query without using WITH AS. Any suggestions using UNION or some other nesting method?
WITH
product AS --filter by dept
(SELECT item
, dept
FROM item_master
WHERE dept in ('353')
),
open_orders AS --view of orders in Status A with ordered units > received units
(SELECT ol.order_no
, ol.item
, ol.location
, oh.po_type
, oh.order_type
, oh.not_before_date
, oh.not_after_date
, oh.otb_eow_date
, SUM(ol.qty_ordered) AS qty_ordered
, SUM(NVL(ol.qty_received,0)) AS qty_received
FROM ordhead oh
, ordloc ol
WHERE oh.order_no = ol.order_no
AND oh.status = 'A'
AND ol.qty_ordered > NVL(ol.qty_received,0)
-- AND ol.order_no in ('18701212') --optional filter for specific PO's
GROUP BY ol.order_no
, ol.item
, ol.location
, oh.po_type
, oh.order_type
, oh.not_before_date
, oh.not_after_date
, oh.otb_eow_date
),
allocations AS --view of all allocations
(SELECT ah.alloc_no
, ah.order_no
, ah.item
, ad.to_loc
, NVL(ad.qty_allocated,0) AS qty_allocated
, NVL(ad.qty_received,0) AS qty_received
FROM alloc_header ah
, alloc_detail ad
WHERE ah.alloc_no = ad.alloc_no
)
SELECT p.dept --main query on above views
, oo.order_no
, oo.po_type
, oo.order_type
, oo.not_before_date
, oo.not_after_date
, oo.otb_eow_date
, oo.item
, CASE WHEN oo.po_type = 0 THEN oo.location ELSE aa.to_loc END AS loc
, SUM(oo.qty_ordered) AS order_qty
, CASE WHEN SUM(NVL(aa.qty_allocated,0)) - SUM(NVL(aa.qty_received,0)) = 0
THEN SUM(oo.qty_ordered) - SUM(NVL(oo.qty_received,0))
ELSE SUM(NVL(aa.qty_allocated,0)) - SUM(NVL(aa.qty_received,0))
END AS open_qty
FROM open_orders oo
, allocations aa
, product p
WHERE oo.order_no = aa.order_no(+)
AND oo.item = aa.item(+)
AND oo.item = p.item
AND (oo.qty_ordered - oo.qty_received) >0
GROUP BY p.dept
, oo.order_no
, oo.po_type
, oo.order_type
, oo.not_before_date
, oo.not_after_date
, oo.otb_eow_date
, oo.item
, CASE WHEN oo.po_type = 0 THEN oo.location ELSE aa.to_loc END
;
CTE's (Common Table Expressions) are just a way of organizing a query by sticking bits of code (that define a "derived" table) at the top that can be reused in the main statement. As such, where product, open_orders, and allocations are mentioned in the FROM clause, you can just swap those words out with the code that defines them:
SELECT p.dept --main query on above views
,
oo.order_no,
oo.po_type,
oo.order_type,
oo.not_before_date,
oo.not_after_date,
oo.otb_eow_date,
oo.item,
CASE
WHEN oo.po_type = 0
THEN oo.location
ELSE aa.to_loc
END AS loc,
SUM(oo.qty_ordered) AS order_qty,
CASE
WHEN SUM(NVL(aa.qty_allocated, 0)) - SUM(NVL(aa.qty_received, 0)) = 0
THEN SUM(oo.qty_ordered) - SUM(NVL(oo.qty_received, 0))
ELSE SUM(NVL(aa.qty_allocated, 0)) - SUM(NVL(aa.qty_received, 0))
END AS open_qty
FROM (
SELECT ol.order_no,
ol.item,
ol.location,
oh.po_type,
oh.order_type,
oh.not_before_date,
oh.not_after_date,
oh.otb_eow_date,
SUM(ol.qty_ordered) AS qty_ordered,
SUM(NVL(ol.qty_received, 0)) AS qty_received
FROM ordhead oh,
ordloc ol
WHERE oh.order_no = ol.order_no
AND oh.STATUS = 'A'
AND ol.qty_ordered > NVL(ol.qty_received, 0)
-- AND ol.order_no in ('18701212') --optional filter for specific PO's
GROUP BY ol.order_no,
ol.item,
ol.location,
oh.po_type,
oh.order_type,
oh.not_before_date,
oh.not_after_date,
oh.otb_eow_date
) oo,
(
SELECT ah.alloc_no,
ah.order_no,
ah.item,
ad.to_loc,
NVL(ad.qty_allocated, 0) AS qty_allocated,
NVL(ad.qty_received, 0) AS qty_received
FROM alloc_header ah,
alloc_detail ad
WHERE ah.alloc_no = ad.alloc_no
) aa,
(
SELECT item,
dept
FROM item_master
WHERE dept IN ('353')
) p
WHERE oo.order_no = aa.order_no(+)
AND oo.item = aa.item(+)
AND oo.item = p.item
AND (oo.qty_ordered - oo.qty_received) > 0
GROUP BY p.dept,
oo.order_no,
oo.po_type,
oo.order_type,
oo.not_before_date,
oo.not_after_date,
oo.otb_eow_date,
oo.item,
CASE
WHEN oo.po_type = 0
THEN oo.location
ELSE aa.to_loc
END;
This is obviously not shortened (but by a few characters), but I get the sense that "shortening" isn't your requirement. You are trying to get this query to work in a product that doesn't support CTEs.
I've tried using CTE, but haven't been able to figure it out. I want to change the multiple rows into one row with multiple columns going accross. Any way to go about this...
Current Result
ern CostPool
111 NULL
111 5
Desired Result
ern CostPool1 CostPool2
111 NULL 5
SELECT first_name, last_name, ern, pc, title, TitleDesc, OfficeTitle, SUM(earned) earned, fypaydate, q
, [RMTS, Support, or Partial Quarter], SUM(CAST([Staff Employment Status] AS INT)) sumEmpStatus, SUM(CAST(countisMHy AS INT)) sumcountisMHy, SUM(CAST(sumisMHy AS INT)) sumisMHy1
, SUM(CAST(sumEligible AS INT)) sumEligible1
, CostPool
FROM (
SELECT
e.first_name, e.last_name
, fss.ern
, fss.pc
, fss4.title
, u.OfficeTitle
, t.TitleDesc
, SUM(fss.gross*fss.[percent]) earned
, fss.fypaydate, fss.q
, cpayfss3, cpaypdq
, CASE WHEN cpayfss3 = cpaypdq THEN '1' --full q
WHEN cpayfss3 < cpaypdq THEN '2' --part q
ELSE 'Check'
END [RMTS, Support, or Partial Quarter]
, CASE WHEN COUNT(DISTINCT rc.isMHy) = 2 THEN '9' --split
WHEN fss.pc = 'A' AND COUNT(DISTINCT rc.isMHy) = 1 AND SUM(CAST(rc.isMHy AS INT)) > 0 THEN '1' --full
WHEN fss.pc IN ('X', 'O', 'W', 'L', 'K') AND SUM(CAST(rc.isMHy AS INT)) > 0 THEN '2' --part
ELSE '0'
END [Staff Employment Status]
, COUNT(DISTINCT rc.isMHy) countisMHy
, SUM(CAST(rc.isMHy AS INT)) sumisMHy
, SUM(CAST(rc.Eligible AS INT)) sumEligible --count distinct too?
, rc.CostPool
FROM [FIN_DataMart].[dbo].[FSSpaydetl_NEW] fss
LEFT JOIN FIN_DataMart.[dbo].[FSSRC_NEW] rc
ON fss.newrc = rc.RC
AND fss.fypaydate = rc.FY
INNER JOIN
(
SELECT ern, fypaydate, q, COUNT(DISTINCT paydate) cpayfss3
FROM [FIN_DataMart].[dbo].[FSSpaydetl_NEW]
GROUP BY fypaydate, q, ern
) fss3
ON fss.ern = fss3.ern
AND fss.fypaydate = fss3.fypaydate
AND fss.q = fss3.q
LEFT JOIN
(
SELECT COUNT(DISTINCT paydate) cpaypdq, fy, q
FROM [FIN_DataMart].[dbo].[FSSPayDateQ]
GROUP BY fy, q
) pdq
ON fss.fypaydate = pdq.fy
AND fss.q = pdq.q
LEFT JOIN
[FIN_DataMart].[dbo].FSSEmployeeInfo e
ON fss.ern = e.ern
INNER JOIN
(
SELECT DISTINCT ern, title, tlvl, fy, q, ROW_NUMBER() OVER (PARTITION BY ern, fy, q ORDER BY title DESC) rn
FROM [FIN_DataMart].[dbo].[FSSpaydetl_NEW]
) fss4
ON fss.ern = fss4.ern
AND fss.fypaydate = fss4.fy
AND fss.q = fss4.q
AND fss4.rn = '1'
LEFT JOIN
(
SELECT TCode, TLevel, GenericTDesc as TitleDesc, EED,
ROW_NUMBER() OVER (PARTITION BY TCode, TLevel ORDER BY EED DESC) rn
FROM [FIN_DataMart].[dbo].FSATitle
) t
ON fss4.title = t.TCode
AND case when fss4.tlvl = '' THEN '01' WHEN fss4.tlvl IS NULL THEN '01' ELSE fss4.tlvl END = t.TLevel
AND t.rn = 1
LEFT JOIN FIN_DataMart.[dbo].[FSSUserERN] u
ON fss.ern = u.ern
WHERE fss.fypaydate = 2015
AND fss.q = 1
AND fss.obj <> '049' AND fss.obj NOT LIKE 'x%'
AND fss.title NOT IN ('10209', '1020B', '10234', '10232', '20202', '21205', '30086', '34201')
GROUP BY
fss.ern
, fss.pc
, fss4.title
, fss.fypaydate, fss.q
, cpayfss3, cpaypdq
, rc.CostPool
, t.TitleDesc
, e.first_name
, e.last_name
, u.OfficeTitle
HAVING SUM(CAST(rc.Eligible AS INT)) >=1
) A
GROUP BY
first_name, last_name, ern, pc, title, fypaydate, q
, [RMTS, Support, or Partial Quarter]
, OfficeTitle
, TitleDesc
, CostPool
ORDER BY first_name, last_name, fypaydate, q
You can look into using the Pivot operator to convert your rows into columns.
https://technet.microsoft.com/en-us/library/ms177410(v=sql.105).aspx
That method would work, although your sample data and expected result do not quite match the massive query you have posted so I cannot provide a more specific example until you provide more test data/expected outputs (and table schema).