SQL Selecting from Sub Query - sql

I have a table with contract ids that have multiple values.
SELECT contractid
,milestoneid
,DATE
,type
,RANK() OVER (PARTITION BY contractid ORDER BY Milestoneid ASC) AS RankNbr
FROM [TSWDATA].[dbo].t_milestone
WHERE contractid = 1056229
contractid milestoneid date type RankNbr
1056 43269 10/10/15 Full 1
1056 43449 10/26/15 GB 2
1056 43456 10/26/15 Submit for Funding 3
1056 43463 10/26/15 Cleared 4
I need to join to the main contract table and pull the contract only when the value 'GB' is the maximum milestoneid.
Can I do this in the where clause?

If you need the records from your contracts table, then you can join to your ranked query. Just change your order by to DESC so the RankNbr 1 will be the maximum milestoneid
SELECT *
FROM [TSWDATA].[dbo].t_contract c
JOIN (
SELECT contractid
,type
,RANK() OVER (PARTITION BY contractid ORDER BY Milestoneid DESC) AS RankNbr
FROM [TSWDATA].[dbo].t_milestone
) ms ON ms.contractid = c.contractid
WHERE
--contractid = 1056229 AND
ms.RankNbr = 1 AND ms.type = 'GB'

Does this work for you?
SELECT contractid
,milestoneid
,DATE
,type
,RANK() OVER (PARTITION BY contractid ORDER BY Milestoneid ASC) AS RankNbr
FROM [TSWDATA].[dbo].t_milestone
WHERE EXISTS (SELECT TOP (1) *
FROM SubTable AS s
WHERE s.type = 'GB'
AND s.contractID = [TSWDATA].[dbo].t_milestone.contractid
ORDER BY s.milestoneID DESC
)
AND contractid = 1056229

Related

How to join to a statement with a row_number() function in SQL?

I a SQL with a row_number() function, and I would like to join on additional tables to get the fields below. How would I accomplish this?
Desired fields:
EMPLOYEE.EMPLID
EMPLOYEE.JOBTITLE
NAME.FIRST_NAME
NAME.LAST_NAME
LOCATION.ADDRESS
PROFESSIONAL_NAME.PROF_NAME
Beginning SQL:
SELECT COUNT(*)
FROM
(
SELECT EMPLOYEE.*, ROW_NUMBER() OVER (PARTITION BY EMPLID ORDER BY
PRIM_ROLE_IND DESC, EMPL_RCD ASC) as RN
FROM EMPLOYEE
WHERE JOB_INDICATOR = 'P'
) dt
WHERE RN = 1
When I try to add a left join at the end, I get an error that says "EMPLOYEE"."EMLID" invalid identifier.
What I'm trying:
SELECT
EMPLOYEE.EMPLID,
EMPLOYEE.JOBTITLE,
NAME.FIRST_NAME,
NAME.LAST_NAME,
LOCATION.ADDRESS,
PROFESSIONAL_NAME.PROF_NAME
FROM
(
SELECT EMPLOYEE.*, ROW_NUMBER() OVER (PARTITION BY EMPLID ORDER BY
PRIM_ROLE_IND DESC, EMPL_RCD ASC) as RN
FROM EMPLOYEE
WHERE JOB_INDICATOR = 'P'
)
LEFT JOIN NAME ON EMPLOYEE.EMPLID = NAME.EMPLID
WHERE
RN = 1
AND
NAME.EFFDT = (
SELECT
MAX (NAME2.EFFDT)
FROM
NAME NAME2
WHERE
NAME2.EMPLID = NAME.EMPLID
AND NAME.NAME_TYPE = 'PRI'
)
AND EMPLOYEE.JOB_INDICATOR = 'P'
You just need to alias your table
...
(
SELECT EMPLOYEE.*, ROW_NUMBER() OVER (PARTITION BY EMPLID ORDER BY
PRIM_ROLE_IND DESC, EMPL_RCD ASC) as RN
FROM EMPLOYEE
WHERE JOB_INDICATOR = 'P'
) temp_employee --add this
LEFT JOIN NAME ON temp_employee.EMPLID = NAME.EMPLID
...
When you create your new table with row_number() in an inner select you essentially create a new table. You need to alias or name this table and then refer to that alias. In the above your from is the inner select, not the EMPLOYEE table. See below for simplified example.
select newtable.field from (select field from mytable) newtable

Select second latest date for each group in the table

hi guys for a report I need to find the second latest date for every specific SKU
down below is the code I am working with.
this is a simplified example.
SKU | plannendstartinflow
11538 2015-03-12
11538 2016-03-12
11538 2017-03-12
33252 2018-02-17
what i need to become is this because it is the second latest date of that SKU
SKU | plannendstartinflow
11538 2016-03-12
code below is the code that is used right now for the latest date
update :
select * from
(select
case when DATEDIFF(MONTH,MAX(PlannedEndInflow),GETDATE()) > 3 then max(PlannedEndInflow) else null end as datum
--case when DATEDIFF(MINUTE,od.PlannedEndInflow,Max(od.PlannedEndInflow)) > 1 then max(od.PlannedEndInflow) else null end as test
,od.odscheduleid
,lc.shortname as line
,ar.erpcode as SKU
,ar.shortname as Article
,od.PlannedEndInflow
,od.[PlannedEndInflow] as second_max_date
,Max(od.PlannedEndInflow) as max_date
,st.shortname as 'status'
,od.[ShortName] as 'order'
,od.[ERPCode]
,od.[ASCode]
,od.[PlannedQuantity] as 'PlannedQuantity [PC]'
,cast(od.[PlannedQuantity]*ar.Volume/100 as decimal(12,2)) as 'PlannedQuantity [HL]'
,od.[PlannedChangeoverTime]
,od.[PlannedSpeed]
,od.[PlannedSpeedRatio],
ROW_NUMBER()over(partition by ar.erpcode order by od.PlannedEndInflow desc) as rn
from(
[RM].[TblDatODSchedule] od
inner join [EM].[TblLstLocation] lc on od.locationid=lc.locationid
inner join [RM].[TblLstART] ar on od.artid=ar.artid
inner join [EM].[TblLstStatus] st on od.statusid=st.statusid
)
--where lc.shortname = 'lb1' and PlannedEndOutflow > '20190101'
group by
ar.ERPCode , lc.ShortName,od.odscheduleid,ar.shortname
,od.[PlannedStartInflow]
,od.[PlannedEndInflow]
,st.shortname
,od.[ShortName]
,od.[ERPCode]
,od.[ASCode]
,od.[PlannedQuantity]
,ar.Volume
,od.[PlannedChangeoverTime]
,od.[PlannedSpeed]
,od.[PlannedSpeedRatio]
) t2 where rn=2;
thanks in advance
You can use the following code to get the second latest date:
select * from
(select SKU,plannendstartinflow,
ROW_NUMBER()over(partition by SKU order by plannendstartinflow desc) as rn
from test
)t where rn=2;
EDIT:
select * from
(select SKU,plannendstartinflow, --similarly add other columns
ROW_NUMBER()over(partition by SKU order by plannendstartinflow desc) as rn
from (
--Put Your Subquery here
)t1
)t2 where rn=2;
EDIT2: To select max and second max date.
select SKU,min(plannendstartinflow) as secondmaxdate,max(plannendstartinflow) as
maxdate from
(select * from (select SKU,plannendstartinflow,
ROW_NUMBER()over(partition by SKU order by plannendstartinflow desc) as rn
from test
)t where rn<3
)t1 group by SKU;

Sql query with join and group by and

I have two table in sql. First one the patient list, second one is their report. all patient's reports are in the report, just with id we can join them. Each patient has some reports (Maybe all the fields of a record is not filled). Now I want to make a report that get the last report of each patient but if some field are empty in the last record of that patient I should fill it with last filled record of that patients records. I have date in the table of reports.
I want to do it for all patients. Here I will add a pic for one patient as an example
In the example above, I want just highlighted ones for this patient in the report.
I have write this query but it give even when a filed in the last record is null while it has data in previous records.
SELECT patient.bartar_id,patient.bartar_enteringthesystem,patient.bartar_proviencename,
patient.bartar_cityname,patient.bartar_coloplastrepname,patient.bartar_consultorname,
patient.bartar_provienceofsurgeryname,patient.bartar_cityofsurgeryname,
patient.bartar_surgeryhospitalname,patient.bartar_doctor,patient.bartar_patientstatusname,
patient.bartar_ostomytypename, patient.bartar_ostomytimename,
r.bartar_date,r.bartar_delay,r.bartar_nextcall,r.new_newcaller,
r.bartar_brandname,r.bartar_pastename,r.bartar_bagname,r.bartar_accname,
r.bartar_pastepermonth,r.bartar_bagepermonth,r.bartar_insuranceinfo,
patient.bartar_deathhealeddate,patient.bartar_dateofseurgery
FROM [Bartar_MSCRM].[dbo].[Filteredbartar_newpaitient] as patient
JOIN (SELECT r.*, row_number() over (partition by r.bartar_patientname
order by r.bartar_date desc) as seqnum
FROM [Bartar_MSCRM].[dbo].[Filteredbartar_callcenterreport] as r
where r.bartar_delay is not null
) r
ON r.bartar_patientname = patient.bartar_newpaitientid and seqnum = 1
ORDER BY patient.bartar_id DESC ;
patient Table
Report Table
Join
Final Report What I want
this is a sample,
in your case you have to get the value of each column in a subquery (either in the join statement, or in the main select statement
example:
inner join (
select distinct bartar_patientname
,(select top 1 bartar_pastePerMonth from [Bartar_MSCRM].[dbo].[Filteredbartar_callcenterreport] c2 where c2.bartar_patientname = cte.bartar_patientname and c2.bartar_pastePerMonth is not null order by c2.bartar_date desc) as bartar_date
,(select top 1 bartar_acc from [Bartar_MSCRM].[dbo].[Filteredbartar_callcenterreport] c2 where c2.bartar_patientname = cte.bartar_patientname and c2.bartar_acc is not null order by c2.bartar_date desc) as bartar_acc
,(select top 1 bartar_insuranceinfo from [Bartar_MSCRM].[dbo].[Filteredbartar_callcenterreport] c2 where c2.bartar_patientname = cte.bartar_patientname and c2.bartar_insuranceinfo is not null order by c2.bartar_date desc) as bartar_insuranceinfo
,(select top 1 bartar_brand from [Bartar_MSCRM].[dbo].[Filteredbartar_callcenterreport] c2 where c2.bartar_patientname = cte.bartar_patientname and c2.bartar_brand is not null order by c2.bartar_date desc) as bartar_brand
from [Bartar_MSCRM].[dbo].[Filteredbartar_callcenterreport] cte
) r
Again, this is a sample of the solution.
Your script is fine as it looks, so I'll just place that on a temporary table for now, and do a per sequence query and filter it by "OR" afterwards.
Please try the script below.
SELECT patient.bartar_id,patient.bartar_enteringthesystem,patient.bartar_proviencename,
patient.bartar_cityname,patient.bartar_coloplastrepname,patient.bartar_consultorname,
patient.bartar_provienceofsurgeryname,patient.bartar_cityofsurgeryname,
patient.bartar_surgeryhospitalname,patient.bartar_doctor,patient.bartar_patientstatusname,
patient.bartar_ostomytypename, patient.bartar_ostomytimename,
r.bartar_date,r.bartar_delay,r.bartar_nextcall,r.new_newcaller,
r.bartar_brandname,r.bartar_pastename,r.bartar_bagname,r.bartar_accname,
r.bartar_pastepermonth,r.bartar_bagepermonth,r.bartar_insuranceinfo,
patient.bartar_deathhealeddate,patient.bartar_dateofseurgery
, ROW_NUMBER() OVER (PARTITION BY r.bartar_newpaitientid, r.bartar_pastepermonth ORDER BY r.bartar_date DESC) AS bartarpaste_sequence
, ROW_NUMBER() OVER (PARTITION BY r.bartar_newpaitientid, r.bartar_acc ORDER BY r.bartar_date DESC) AS bartaracc_sequence
, ROW_NUMBER() OVER (PARTITION BY r.bartar_newpaitientid, r.bartar_insuranceinfo ORDER BY r.bartar_date DESC) AS bartarins_sequence
, ROW_NUMBER() OVER (PARTITION BY r.bartar_newpaitientid, r.bartar_brandname ORDER BY r.bartar_date DESC) AS bartarbrd_sequence
INTO #tmpPatientReport
FROM [Bartar_MSCRM].[dbo].[Filteredbartar_newpaitient] as patient
JOIN (SELECT r.*, row_number() over (partition by r.bartar_patientname
order by r.bartar_date desc) as seqnum
FROM [Bartar_MSCRM].[dbo].[Filteredbartar_callcenterreport] as r
where r.bartar_delay is not null
) r
ON r.bartar_patientname = patient.bartar_newpaitientid and seqnum = 1
ORDER BY patient.bartar_id DESC;
SELECT
*
FROM #tmpPatientReport
WHERE
bartarpaste_sequence = 1
OR bartaracc_sequence = 1
OR bartarins_sequence = 1
OR bartarbrd_sequence = 1
just do join for each column
JOIN (SELECT r.colx, row_number() over (partition by r.bartar_patientname
order by r.bartar_date desc) as seqnum
FROM [Bartar_MSCRM].[dbo].[Filteredbartar_callcenterreport] as r
where r.bartar_delay is not null and r.colx in not null
) rx
ON rx.bartar_patientname = patient.bartar_newpaitientid and seqnum = 1

RANK() OVER ignore equal ranks

I have this query
SELECT
patientid,
practiceid,
visitcount
FROM
(
SELECT
patientid,
practiceid ,
visitcount,
RANK() OVER (PARTITION BY patientid ORDER BY visitcount DESC) as Rank
FROM
aco.patients_practices
WHERE practiceid in (select id from aco.practices where parentaco = 30982) and isprimary = 0
) AS A
WHERE
Rank = 1
Here are some results
patientid practiceid visitcount
157053 30976 6
158463 30974 2
187772 30973 15
187797 30971 1
187797 30975 1
Notice the last 2 patientid's are the same and have the same visitcount hence the same rank. How can I omit these records with equal ranks completely from the output?
Thanks!
You can eliminate them by counting them and including them in the where clause. The following query counts them using logic similar to the rank -- the number of times the patient has the same visitcount:
SELECT patientid, practiceid, visitcount
FROM (SELECT patientid, practiceid, visitcount,
RANK() OVER (PARTITION BY patientid ORDER BY visitcount DESC) as Rank,
COUNT(*) over (PARTITION by patientid, visitcount) as RankCount
FROM aco.patients_practices
WHERE practiceid in (select id from aco.practices where parentaco = 30982) and isprimary = 0
) A
WHERE Rank = 1 and RankCount = 1
I do notice that the practiceid is different in the last two records. It seems that you still want to eliminate both, though.

Oracle SQL Query Assistance

Given a table:
ID NUMBER
OBJECTID NUMBER
CATEGORYID NUMBER
SCORE NUMBER
SCOREDATE DATE
Is it possible to efficiently retrieve the last score (based on SCOREDATE) in each distinct category for a given object in one query?
Try:
select v.* from (
select category_id,
score,
scoredate,
row_number() over (partition by category_id order by scoredate desc) rn
from MyTable) v
where rn=1
What you want falls into the [greatest-n-per-group] tag. One way to achieve the result:
SELECT
t.CategoryId
, t.Score
FROM
( SELECT
CategoryId
, MAX(ScoreDate) AS LastScoreDate
FROM
TableX
WHERE
ObjectId = #ObjectId
GROUP BY
CategoryId
) AS grp
JOIN
TableX AS t
ON grp.Category = t.CategoryId
AND grp.LastScoreDate = t.ScoreDate
WHERE
t.ObjectId = #ObjectId