I am running one query and getting following results
Select *
from
(Select ROW_NUMBER() over
(partition by [HOSP_CODE],[MRN]
order by [HOSP_CODE],MRN,ADM_DATETIME ) as rownumber,*
from Live.tempnewbornbundling) as a
order by [HOSP_CODE],MRN,ADM_DATETIME
DATA
Rownumber key MRn hospcode adm_date sep_date Sequence
--------- ------- ------ -------- ---------------- ---------------- --------
1 7099222 544607 3 22/07/2011 04:55 22/07/2011 10:44 First
2 7099223 544607 3 22/07/2011 10:45 25/07/2011 19:43 Middle
3 7099224 544607 3 25/07/2011 19:44 26/07/2011 11:29 Middle
4 7099225 544607 3 27/07/2011 12:30 27/07/2011 19:30 First
5 7099226 544607 3 27/07/2011 19:31 28/07/2011 19:31 Final
1 7099227 559282 3 03/07/2011 22:50 03/07/2011 23:51 First
2 7099228 559282 3 03/07/2011 23:52 04/07/2011 15:30 Middle
3 7099229 559282 3 04/07/2011 15:31 04/07/2011 17:59 Final
4 7099230 559282 3 05/07/2011 18:00 05/07/2011 18:05 First
5 7099231 559282 3 05/07/2011 18:06 09/07/2011 14:58 Final
How can I further make partitions and assign row numbers based on sequence values,
for example I want to restart rownumber each time there is first in same group HOSPcode, MRN
Rownumber key MRn hospcode adm_date sep_date Sequence New rownumber
--------- ------- ------ -------- ---------------- ---------------- -------- -------------
1 7099222 544607 3 22/07/2011 04:55 22/07/2011 10:44 First 1
2 7099223 544607 3 22/07/2011 10:45 25/07/2011 19:43 Middle 2
3 7099224 544607 3 25/07/2011 19:44 26/07/2011 11:29 Middle 3
4 7099225 544607 3 27/07/2011 12:30 27/07/2011 19:30 First 1
5 7099226 544607 3 27/07/2011 19:31 28/07/2011 19:31 Final 2
1 7099227 559282 3 03/07/2011 22:50 03/07/2011 23:51 First 1
2 7099228 559282 3 03/07/2011 23:52 04/07/2011 15:30 Middle 2
3 7099229 559282 3 04/07/2011 15:31 04/07/2011 17:59 Final 3
4 7099230 559282 3 05/07/2011 18:00 05/07/2011 18:05 First 1
5 7099231 559282 3 05/07/2011 18:06 09/07/2011 14:58 Final 2
You should be able to do this with a recursive CTE
You will want to do the recursion on the rownumber (that will make sure you end), and then just keep incrementing a new rownumber column everytime you recurse, resetting when you hit first. I believe the below answer should work. I would store the previous query in a temp table
WITH FinalValues (RowNumber, Key, MRN, HospCode, adm_date, sep_date,
sequence, NewRowNum)
AS
(
-- Anchor member definition
SELECT RowNumber, Key, MRN, HospCode, adm_date, sep_date,
sequence, 1 AS NewRowNum
FROM PreviousQuery
WHERE RowNumber = 1
UNION ALL
-- Recursive member definition
SELECT P.RowNumber, P.Key, P.MRN, P.HospCode, P.adm_date, P.sep_date,
P.sequence,
CASE WHEN P.sequence = 'First' THEN 1 ELSE NewRowNum + 1 END AS NewRowNum
FROM PreviousQuery AS P
INNER JOIN FinalValues
ON FinalValues.RowNumber = P.RowNumber + 1
)
-- Statement that executes the CTE
SELECT *
FROM FinalValues;
GO
Related
I want to create a select query in SQL Server where I group the rows by a column (BaseId) and also order them by Status, RTime and Version. I want to add a column "isFirst" that has the value 1 if the BaseId value is the first in the group, and 0 if it's not.
My sample table:
Table name: Head
Id BaseId Name RTime Status Version
2 2 abc 04-12 12:34 1 1
3 3 xyz 04-12 13:10 9 1
4 2 abc 04-13 14:25 0 2
5 3 xyz 04-14 12:34 0 2
6 3 xyz 04-14 13:10 9 3
7 3 xyz 04-16 14:25 1 4
8 2 abc 04-16 17:40 1 3
9 9 sql 04-17 02:23 9 1
10 9 sql 04-17 07:31 0 2
Expected result:
isFirst Id BaseId Name RTime Status Version
1 10 9 sql 04-17 07:31 0 2
0 9 9 sql 04-17 02:23 9 1
1 5 3 xyz 04-14 12:34 0 2
0 7 3 xyz 04-16 14:25 1 4
0 6 3 xyz 04-14 13:10 9 3
0 3 3 xyz 04-12 13:10 9 1
1 4 2 abc 04-13 14:25 0 2
0 8 2 abc 04-16 17:40 1 3
0 2 2 abc 04-12 12:34 1 1
My query now looks like this:
SELECT *
FROM Head
ORDER BY BaseId desc, Status, RTime desc, Version desc
I think I should use CASE to create the isFirst column, but I've had no luck so far. Anyone could help me?
You can use row_number() and a case expression:
select
case when row_number() over(
partition by BaseId
order by Status, RTime desc, Version desc
) = 1
then 1
else 0
end isFirst,
h.*
from head h
order by BaseId desc, Status, RTime desc, Version desc
I have a table with source, dest, and time of the trip. I want to find list of all the sources that had same destination for the first and last trip of the day. Table looks like below:
Source Dest Trip_Time
1 2 2/1/2019 6:00
2 3 2/1/2019 7:00
4 2 2/1/2019 7:00
1 3 2/1/2019 8:00
2 1 2/1/2019 9:00
3 1 2/1/2019 9:00
4 1 2/1/2019 9:00
1 4 2/1/2019 15:00
2 1 2/1/2019 17:30
3 5 2/1/2019 17:30
4 5 2/1/2019 17:30
2 3 2/1/2019 19:45
3 1 2/1/2019 19:45
5 2 2/1/2019 19:45
1 4 2/2/2019 17:00
1 3 2/2/2019 21:00
I have figured out a query to get what I wanted, but I was wondering if there is more optimal way of achieving the result, especially the one that'll work with millions of rows.
select source, max(first_trip) ft, max(last_trip) lt from
(select source, case when (a.max) = 1 then (dest) end as first_trip,
case when (a.min) = 1 then (dest) end as last_trip from (select source, dest, time_trip,
Row_Number() Over (partition by source order by time_trip desc) as max,
Row_Number() Over (partition by source order by time_trip asc) as min from trips) a
where a.max = 1 or a.min = 1) b
group by b.source) c where ft = lt```
Expected result:
caller fc lc
2 3 3
3 1 1
5 2 2
One method is to use first_value() and last_value(). Date functions are notoriously dependent on the database, but you need to extract the date from the trip_time. The following illustrates the idea but the date function could differ on your database:
select distinct source, cast(trip_time as date)
from (select t.*,
first_value(dest) over (partition by source, cast(trip_time as date) order by trip_time asc) as first_dest,
first_value(dest) over (partition by source, cast(trip_time as date) order by trip_time desc) as last_dest
from trips t
) t
where first_dest = last_dest;
I'm working in iMIS CMS (iMIS 200) and trying to create an IQA (an iMIS query, using SQL) that will give me a timetable of slots assigned to people per day (I've got this working); but then I want to be able to filter that timetable on a person's profile so they just see the slots they are assigned to.
(This is for auditions for an orchestra. So people make an application per instrument, then those applications are assigned to audition slots, of which there are several slots per day)
As the start/end times for slots are calculated using SUM OVER, when I filter this query by the person ID, I lose the correct start/end times for slots (as the other slots aren't in the data for it to SUM, I guess!)
Table structure:
tblContacts
===========
ContactID ContactName
---------------------------
1 Steve Jones
2 Clare Philips
3 Bob Smith
4 Helen Winters
5 Graham North
6 Sarah Stuart
tblApplications
===============
AppID FKContactID Instrument
-----------------------------------
1 1 Violin
2 1 Viola
3 2 Cello
4 3 Cello
5 4 Trumpet
6 5 Clarinet
7 5 Horn
8 6 Trumpet
tblAuditionDays
===============
AudDayID AudDayDate AudDayVenue AudDayStart
-------------------------------------------------
1 16-Sep-19 London 10:00
2 17-Sep-19 Manchester 10:00
3 18-Sep-19 Birmingham 13:30
4 19-Sep-19 Leeds 10:00
5 19-Sep-19 Glasgow 11:30
tblAuditionSlots
================
SlotID FKAudDayID SlotOrder SlotType SlotDuration FKAppID
-----------------------------------------------------------------
1 1 1 Audition 20 3
2 1 2 Audition 20 4
3 1 3 Chat 10 3
4 1 5 Chat 10 4
5 1 4 Audition 20
6 2 1 Audition 20 1
7 2 2 Audition 20 6
8 2 4 Chat 10 6
9 2 3 Chat 10 1
10 2 5 Audition 20
11 3 2 Chat 10 8
12 3 1 Audition 20 2
13 3 4 Chat 5 2
14 3 3 Audition 20 8
15 5 1 Audition 30 5
16 5 2 Audition 30 7
17 5 3 Chat 15 7
18 5 4 Chat 15 5
Current SQL for listing all the slots each day (in date/slot order, with the slot timings calculcated correctly) is:
SELECT
[tblAuditionSlots].[SlotOrder] as [Order],
CASE
WHEN
SUM([tblAuditionSlots].[SlotDuration]) OVER (PARTITION BY [tblAuditionDays].[FKAudDayID] ORDER BY [tblAuditionSlots].[SlotOrder] ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING) is null
THEN
CONVERT(VARCHAR(5), [tblAuditionDays].[AudDayStart], 108)
ELSE
CONVERT(VARCHAR(5), Dateadd(minute, SUM([tblAuditionSlots].[SlotDuration]) OVER (PARTITION BY [tblAuditionDays].[FKAudDayID] ORDER BY [tblAuditionSlots].[SlotOrder] ROWS BETWEEN UNBOUNDED PRECEDING AND 1 PRECEDING), [tblAuditionDays].[AudDayStart]), 108)
END
+ ' - ' +
CASE
WHEN
SUM([tblAuditionSlots].[SlotDuration]) OVER (PARTITION BY [tblAuditionDays].[FKAudDayID] ORDER BY [tblAuditionSlots].[SlotOrder] ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) is null
THEN
CONVERT(VARCHAR(5), [tblAuditionDays].[AudDayStart], 108)
ELSE
CONVERT(VARCHAR(5), Dateadd(minute, SUM([tblAuditionSlots].[SlotDuration]) OVER (PARTITION BY [tblAuditionDays].[FKAudDayID] ORDER BY [tblAuditionSlots].[SlotOrder] ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW), [tblAuditionDays].[AudDayStart]), 108)
END AS [Slot],
[tblAuditionSlots].[SlotType] AS [Type],
[tblContacts].[ContactName] as [Name],
FROM
tblAuditionSlots
LEFT JOIN tblAuditionDays ON tblAuditionSlots.FKAudDayID = tblAuditionDays.AudDayID
LEFT JOIN tblApplications ON tblAuditionSlots.FKAppID = tblApplications.AppID
LEFT JOIN tblContacts ON tblApplications.FKContactID = tblContacts.ContactID
GROUP BY
[tblAuditionSlots].[SlotOrder],
[tblAuditionSlots].[SlotType],
[tblAuditionSlots].[SlotDuration],
[tblAuditionDays].[AudDayStart],
[tblContacts].[ContactName],
[tblContacts].[ContactID],
[tblAuditionDays].[AudDayID],
[tblAuditionDays].[AudDayDate]
ORDER BY
[tblAuditionDays].[DayDate],
[tblAuditionSlots].[Order]
iMIS, the CMS we're using, is limited by what you can create in an IQA (query).
You can basically insert (some) SQL as a column and give it an alias; you can add (non-calculated) fields to the order by; you can't really control the Group By (whatever fields are added are included in the Group By).
Ultimately, I'd like to be able to filter this by a Contact ID so I can see all their audition slots, but with the times correctly calculated.
From the sample data, for example:
STEVE JONES AUDITIONS
=====================
Date Slot Venue Type Instrument
----------------------------------------------------------------
17-Sep-19 10:00 - 10:20 Manchester Audition Violin
17-Sep-19 10:40 - 10:50 Manchester Chat Violin
18-Sep-19 13:30 - 13:50 Birmingham Audition Viola
18-Sep-19 14:30 - 14:35 Birmingham Chat Viola
HELEN WINTERS AUDITIONS
=======================
Date Slot Venue Type Instrument
----------------------------------------------------------------
19-Sep-19 11:30 - 12:00 Glasgow Audition Trumpet
19-Sep-19 12:45 - 13:00 Glasgow Chat Trumpet
Hopefully that all makes sense and I've provided enough information.
(In this version of iMIS [200], you can't do subqueries, in case that comes up...)
Thanks so much in advance for whatever help/tips/advice you can offer!
Chris
I am kind of stuck in querying my timelogs table,
the following are the sample data:
TimelogId EmployeeId RecordDate RecordTime Type
--------- ---------- ---------- ---------- ----
1 4 2016-07-01 07:18:37 1
2 4 2016-07-01 12:03:14 2
5 4 2016-07-01 12:08:02 1
6 4 2016-07-01 18:02:03 2
7 6 2016-07-19 07:24:15 1
8 5 2016-07-19 07:26:03 1
9 6 2016-07-19 12:15:26 2
10 5 2016-07-19 12:35:17 2
13 5 2016-07-19 12:36:14 1
16 6 2016-07-19 12:45:45 1
17 6 2016-07-19 17:10:22 2
18 5 2016-07-19 18:43:09 2
The required output:
Date EmployeeId Time_In Time_Out Time_In Time_Out
------- ---------- -------- -------- ------- -------
2016-07-01 4 07:18:37 12:03:14 12:08:03 18:02:03
2016-07-19 6 07:24:15 12:15:26 12:45:45 17:10:22
2016-07-19 5 07:26:03 12:35:17 12:36:14 18:43:08
Where Type (1) = time in and Type (2) = time out.
Employees are required to logout at 12nn then log back in again after a couple of minutes.
I tried using pivot based from the previous questions that i read here. Though this is the first time i tried to use pivot in tables.
select
*
FROM
(
select
EmployeeID,
RecordDate,
RecordTime,
Type
from tblTimeLogs
) d
PIVOT(
Max(RecordTime) <---- I think the problem is right around here
FOR Type in ([1],[2]) <----- plus i can't seem to rename this column names maybe i'll read a little further on this.
) piv;
Output of query:
EmployeeID RecordDate 1 2
---------- ---------- ------ ------
4 2016-07-01 12:08:02 18:02:03
5 2016-07-19 12:36:14 18:43:09
6 2016-07-19 12:45:45 17:10:22
is this possible? Thanks. :D
Edit:
as suggested by vercelli, another scenario like for example the user forgot that he/she already timed in just a couple of minutes ago so she timed in again.
e.g.
TimelogId EmployeeId RecordDate RecordTime Type
--------- ---------- ---------- ---------- ----
1 4 2016-07-01 07:18:37 1
2 4 2016-07-01 12:03:14 2
5 4 2016-07-01 12:08:02 1
6 4 2016-07-01 18:02:03 2
7 6 2016-07-19 07:24:15 1
8 5 2016-07-19 07:26:03 1
9 6 2016-07-19 12:15:26 2
10 5 2016-07-19 12:35:17 2
13 5 2016-07-19 12:36:14 1
16 6 2016-07-19 12:45:45 1
17 6 2016-07-19 17:10:22 2
18 5 2016-07-19 18:43:09 2
19 5 2016-07-20 08:13:35 1 <--- Time in
20 5 2016-07-20 08:14:35 1 <--- Timed In again
21 5 2016-07-20 12:15:12 2 <--- Time Out
I tried using the query of Mr. Vercelli:
select
EmployeeID as Emp, RecordDate, [1] as Time_In1, [2] as Time_Out1, [3] as Time_In2, [4] as Time_out2
FROM
(
select
EmployeeID,
RecordDate,
RecordTime,
ROW_NUMBER () over (partition by EmployeeId, RecordDate order by RecordTime, type) as rn
from tblTimeLogs
) d
PIVOT(
max(RecordTime)
FOR rn in ([1],[2],[3],[4])
) as piv;
Output of the new query:
Emp RecordDate Time_In1 Time_Out1 Time_In2 Time_Out2
---- ---------- --------- --------- -------- ---------
4 2016-07-01 07:18:37 12:03:14 12:08:02 18:02:03
5 2016-07-19 07:26:03 12:35:17 12:36:14 18:43:09
5 2016-07-20 08:13:35 08:14:35 12:15:12 Null <--- the problem is right around this portion
6 2016-07-19 07:24:15 12:15:26 12:45:45 17:10:22
Expected Output:
Emp RecordDate Time_In1 Time_Out1 Time_In2 Time_Out2
---- ---------- --------- --------- -------- ---------
4 2016-07-01 07:18:37 12:03:14 12:08:02 18:02:03
5 2016-07-19 07:26:03 12:35:17 12:36:14 18:43:09
5 2016-07-20 08:13:35 12:15:12 08:14:35 Null <--- the second time in would fall on the second 5th column (Time_In2) since the **Type** value is = 1
6 2016-07-19 07:24:15 12:15:26 12:45:45 17:10:22
Thanks for the help guys :D. I'm learning new things from this problem.
I think this is what you are looking for. Demo:
select
EmployeeID as Emp, RecordDate, [1] as Time_In1, [2] as Time_Out1, [3] as Time_In2, [4] as Time_out2
FROM
(
select
EmployeeID,
RecordDate,
RecordTime,
ROW_NUMBER () over (partition by EmployeeId, RecordDate order by RecordTime, type) as rn
from tblTimeLogs
) d
PIVOT(
max(RecordTime)
FOR rn in ([1],[2],[3],[4])
) as piv;
OUPUT
Emp RecordDate Time_In1 Time_Out1 Time_In2 Time_out2
4 2016-07-01 07:18:37 12:03:14 12:08:02 18:02:03
5 2016-07-19 07:26:03 12:35:17 12:36:14 18:43:09
6 2016-07-19 07:24:15 12:15:26 12:45:45 17:10:22
DEMO HERE
---Table Creattion Scripts
create table #test
(
employeeid int,
recorddate date,
recordtime time,
typee int
)
insert into #test values( 4 , '2016-07-01', '07:18:37', 1)
insert into #test values( 4 , '2016-07-01', '12:03:14', 2)
insert into #test values( 4 , '2016-07-01', '12:08:02', 1)
insert into #test values( 4 , '2016-07-01', '18:02:03', 2)
Query
;with cte
as
(
select
employeeid,
max(recorddate) as recorddate,
min(recordtime) as timein,
max(recordtime) as Timein1 ,
lead(min(recordtime)) over (partition by employeeid order by min(recordtime)) as 'timeout1',
lead(max(recordtime)) over (partition by employeeid order by max(recordtime)) as 'timeout2'
from #test
group by
employeeid,typee
)
select employeeid,recorddate,timein,timeout1,timein1,timeout2
from cte
where timeout1 is not null and timeout2 is not null
Hello all I am new to Access I am trying to get data from one table that is dependent on another table. So basically I have one table named MUE_Values that stores 2 fields (cpt_code) and (mue_value). I have another table called Claims... this table holds approximately 75 fields. My question is- from the claims table I want to get all the fields where the (cpt_code) matches the (cpt_code) from the MUE_Values TABLE and the (units) > (mue_value),also I want to get all the rows where the (cpt_code) matches the same (cpt_code) in the claims table and was on the same date for the (patient_ssn) whether or not the (units) > (mue_values).
For Example:
Claims Table
ID patient_ssn cpt_code from_date units Field5 Field6 Field7 etc
1 098345567 12345 10/27/2015 1
2 098345567 12345 10/27/2015 1
3 098345567 09786 10/2/2015 5
4 098345567 54321 10/7/2015 3
5 098345567 87654 10/5/2015 2
6 098345567 87654 10/6/2015 3
7 789797979 65432 10/7/2015 1
8 789797979 65432 10/3/2015 2
9 789797979 76543 10/13/2015 5
10 789797979 76541 10/13/2015 1
11 789797979 12345 10/27/2015 1
12 789797979 87654 10/27/2015 0
MUE_values TABLE
cpt_code mue_value
12345 1
23456 1
34567 1
45678 1
54321 2
56789 4
65432 1
76543 3
87654 2
98765 2
So this query alone gets the patient data with the same date and a count of the dates > 1 with that same (cpt_code).
SELECT Claims.patient_ssn, Claims.from_date, Count(Claims.from_date) AS CountOffrom_date
FROM Claims INNER JOIN MUE_values ON Claims.cpt_code = MUE_values.cpt_code
WHERE (((Claims.cpt_code)=[MUE_values].[cpt_code]))
GROUP BY Claims.patient_ssn, Claims.from_date, MUE_values.cpt_code
HAVING (((Count(Claims.[from_date]))>1))
WHERE (((Claims.units)>[mue_value]));
But when I put together into one query it returns all the rows with the same from_date instead of just the one from the query above along with the other four from the first subquery
SELECT Claims.*
FROM Claims
WHERE EXISTS(SELECT *
FROM MUE_values
WHERE Claims.cpt_code = MUE_values.cpt_code AND
Claims.units > MUE_values.[mue_value]
) OR
EXISTS (SELECT Claims.patient_ssn, Claims.from_date, Count(Claims.from_date) AS CountOffrom_date
FROM Claims INNER JOIN MUE_values ON Claims.cpt_code = MUE_values.cpt_code
WHERE (((Claims.cpt_code)=[MUE_values].[cpt_code]))
GROUP BY Claims.patient_ssn, Claims.from_date, MUE_values.cpt_code
HAVING (((Count(Claims.[from_date]))>1)));
This should be the result:
ID patient_ssn cpt_code from_date units Field5 Field6 Field7 etc...
1 098345567 12345 10/27/2015 1
2 098345567 12345 10/27/2015 1
4 098345567 54321 10/7/2015 3
6 098345567 87654 10/6/2015 3
8 789797979 65432 10/3/2015 2
9 789797979 76543 10/13/2015 5
Instead I am Getting this result:
ID patient_ssn cpt_code from_date units Field5 Field6 Field7 etc...
1 098345567 12345 10/27/2015 1
2 098345567 12345 10/27/2015 1
3 098345567 09786 10/2/2015 5
4 098345567 54321 10/7/2015 3
5 098345567 87654 10/5/2015 2
6 098345567 87654 10/6/2015 3
7 789797979 65432 10/7/2015 1
8 789797979 65432 10/3/2015 2
9 789797979 76543 10/13/2015 5
10 789797979 76541 10/13/2015 1
11 789797979 12345 10/27/2015 1
12 789797979 87654 10/27/2015 0
When I read your requirements, it sounds like EXISTS:
SELECT Claims.*
FROM Claims
WHERE EXISTS (SELECT 1
FROM MUE_values
WHERE Claims.cpt_code = MUE_values.cpt_code AND
Claims.units > MUE_values.[mue_value]
) OR
EXISTS (SELECT 1
FROM MUE_values
WHERE Claims.cpt_code = MUE_values.cpt_code AND
Claims.patent_ssn = MUE_values.patient_ssn
);
However, I have no idea what "same date" means, because one table definitely does not have a date.