I'm trying to run a query from a HR table. I'm bringing in all employees and their dependents who share the same 'Primary_Key_Value'. My statement works but I'm getting duplicates because some dependents have multiple MED_COV_EFFECTIVE_DATEs. I need to bring in only the lastest or MAX date. When I try to use the MAX(MED_COV_EFFECTIVE_DATE) function, I'm getting errors. Can someone please help me?
SELECT DISTINCT PRIMARY_KEY_VALUE, RECORD_ID, LAST_NAME, FIRST_NAME, DATE_OF_BIRTH, HIRE_DATE,
RELATIONSHIP_CODE, MED_COV_EFFECTIVE_DATE, SOCIAL_SECURITY_NUMBER
FROM COVERAGE_TABLE T1
WHERE T1.PRIMARY_KEY_VALUE IN
(
SELECT T2.PRIMARY_KEY_VALUE
FROM COVERAGE_TABLE T2
WHERE T2.HIRE_DATE IS NOT NULL
)
ORDER BY PRIMARY_KEY_VALUE, RECORD_ID
Dang, wasn't thinking about inner select can only return 1 column earlier. Try something like this:
SELECT T2.PRIMARY_KEY_VALUE, MAX(T2.Med_Cov_Effective_Date)
INTO #MostRecentCoveredKeys
FROM COVERAGE_TABLE T2
WHERE T2.HIRE_DATE IS NOT NULL
GROUP BY T2.Primary_Key_Value
This should give you a unique set of Primary_Key_Values.
Or CTE Version:
; WITH MostRecentCoveredKeys
AS
SELECT T2.PRIMARY_KEY_VALUE, MAX(T2.Med_Cov_Effective_Date)
FROM COVERAGE_TABLE T2
WHERE T2.HIRE_DATE IS NOT NULL
GROUP BY T2.Primary_Key_Value
Then JOIN the original table and cte (or temp table) like so:
SELECT PRIMARY_KEY_VALUE, RECORD_ID, LAST_NAME, FIRST_NAME, DATE_OF_BIRTH,
HIRE_DATE, RELATIONSHIP_CODE, MED_COV_EFFECTIVE_DATE,
SOCIAL_SECURITY_NUMBER
FROM COVERAGE_TABLE T1
INNER JOIN MostRecentCoveredKeys mrck
ON mrck.Primary_Key_Value = T1.Primary_Key_Value
ORDER BY T1.PRIMARY_KEY_VALUE, T1.RECORD_ID
--you need to include the '#' in front of table name
--on join if using the temp table version
--DROP TABLE #MostRecentCoveredKeys
This query will fetch the latest data:
SELECT B.PRIMARY_KEY_VALUE, B.RECORD_ID, B.LAST_NAME, B.FIRST_NAME,
B.DATE_OF_BIRTH, B.HIRE_DATE, B.RELATIONSHIP_CODE,
B.MED_COV_EFFECTIVE_DATE, B.SOCIAL_SECURITY_NUMBER
FROM
(SELECT PRIMARY_KEY_VALUE, MAX(MED_COV_EFFECTIVE_DATE) MAX_DATE
FROM COVERAGE_TABLE
WHERE HIRE_DATE IS NOT NULL
GROUP BY PRIMARY_KEY_VALUE) A INNER JOIN
(SELECT * FROM COVERAGE_TABLE
WHERE HIRE_DATE IS NOT NULL) B
ON A.PRIMARY_KEY_VALUE=B.PRIMARY_KEY_VALUE AND A.MAX_DATE=B.MED_COV_EFFECTIVE_DATE;
;with a as
(
select
*
,row_number() over(partition by PRIMARY_KEY_VALUE, order by Med_Cov_Effective_Date desc) rn
FROM COVERAGE_TABLE T1
WHERE HIRE_DATE IS NOT NULL
)
select *
from a
where rn=1
ORDER BY PRIMARY_KEY_VALUE, RECORD_ID
Related
I would like to run a select statement that runs and select only the newest record by Recored_timestampe field for the keys teacher_id and student_id. So any time, it runs it needs to provide only one record. how could I do it, please? The output could be without the field Recored_timestampe. Thanks
Using the window function,partitioned by teacher_id and student_id and sorting it by recorded_timestamp will give you the desired result.
select * from(select teacher_id,student_id,teacher_name,comment ,recorded_timestamp, row_number() over(partition by teacher_id,student_id order by recorded_timestamp desc)as rownum from temp0607)out1 where rownum=1
Also you may have to look at the way recorded_timestamp is stored. If it is stored as string, you can convert it into timestamp using from_unixtime(unix_timestamp(recorded_timestamp,'dd/MM/yyyy HH:mm'),'dd/MM/yyyy HH:mm')
First, arrange the record by datetime
SELECT *,RANK() OVER (PARTITION BY student_id ORDER BY Recored_timestamp desc) as ranking
FROM #temp
Then, if you want to know the newest record with student_id which is not null, then you can use OUTER APPLY to add a column which is non-NULL student_id.
OUTER APPLY (SELECT student_id
FROM #temp
WHERE #temp.teacher_id = ranktable.teacher_id
AND student_id IS NOT NULL
) AS jointable
Here is an example:
Create Table #temp
(
teacher_id int
,student_id int
,teacher_name varchar(40)
,comment varchar(100)
,Recored_timestamp datetime
)
INSERT INTO #temp
VALUES
(449,111,'lucy','Could be better','2021-05-04 07:00:00.000')
,(449,null,'lucy','smily','2021-05-11 07:00:00.000')
,(449,111,'lucy','not listening','2021-05-08 07:00:00.000')
,(448,null,'Toni','Good','2021-06-04 09:00:00.000')
,(448,222,'Toni','not doing as expected','2021-06-04 08:00:00.000')
SELECT DISTINCT teacher_id,
jointable.student_id,
teacher_name,
comment,
Recored_timestamp,
ranking
FROM
(
SELECT *,RANK() OVER (PARTITION BY teacher_id ORDER BY Recored_timestamp DESC) AS ranking
FROM #temp
) AS ranktable
OUTER APPLY (SELECT student_id
FROM #temp
WHERE #temp.teacher_id = ranktable.teacher_id
AND student_id IS NOT NULL
) AS jointable
WHERE ranking = 1 --only newest record will be extracted
Drop table #temp
You can base from this query to get the newest data.
SELECT TOP 1 * FROM tablename T1
INNER JOIN(SELECT teacher_id, Max(Recored_timestamp) as MaxDate from tablename GROUP BY teacher_id) T2 ON T2.teacher_id = T1.teacher_id AND T1.Recored_timestamp = T2.MaxDate
Test Table
create table Test (
Id integer,
Store_N varchar(25),
Department varchar(25)
);
INSERT INTO Test (Id, Store_N, Department )
Values (25,'1','A'), (67,'1','A'), (34,'1','A'), (97,'1','C'),
(21,'1','C'), (268,'1','B'), (456,'2','A'), (349,'2','A'),
(935,'2','B'), (36,'3','B'), (637,'3','B'), (388,'3','B'),
(891,'3','B'), (344,'4','A'), (763,'4','A'), (836,'4','A')
SELECT * , ROW_NUMBER() OVER( Partition BY Store_N ORDER BY Store_N ) AS AA
FROM Test;
Result is
I need to exclude all stores which have only one department and have the only DISTINCT department for each store. The result looks like this
And this is code
SELECT DISTINCT TB4.Department, TB4.Store_N
From
(
SELECT TB0.Store_N, TB0.Department FROM Test TB0
INNER JOIN
(
SELECT TB2.Store_N , Count(*) AS AA1
FROM
(
SELECT DISTINCT TB1.Department , TB1.Store_N
FROM
( SELECT * , ROW_NUMBER() OVER( Partition BY Store_N ORDER BY Store_N ) AA
FROM Test ) TB1
) TB2
group by TB2.Store_N
HAVING
COUNT(*) > 1 ) TB3
ON TB0.Store_N = TB3.Store_N
) TB4
Now the question how to simplify this code?
Thank you
You can basically do:
select store_n, department
from test
group by store_n, department;
But, you want to exclude stores that have only one department, so lets do a count:
select store_n, department
from (select store_n, department, count(*) over (partition by store_n) as cnt
from test
group by store_n, department
) t
where cnt > 1;
Here is a SQL Fiddle.
You are going a long way round to get the functionality of the "GROUP BY" clause
SELECT TB2.Store_N , TB2.Department
FROM
(
SELECT Department , Store_N, count(Id) as c
FROM Test
GROUP BY Department, Store_N) as TB2
WHERE TB2.c > 1
I am having an issue trying to select one row per city name. This is the following collection I am getting:
This is my query so far:
select pl.PlaceId,
pl.Name,
pop.NumberOfPeople,
pop.Year
from dbo.Places pl
inner join dbo.Populations pop
on pop.PlaceId = pl.PlaceId
where pop.NumberOfPeople >= 1000
and pop.NumberOfPeople <= 99999
I am trying to get it to where it only selects a city one time, but uses the most recent date. So in the above picture, I would only see Abbeville for 2016 and not 2015. I believe I need to do either a group by or do a sub query to flatten the results. If anybody has any advice on how I can handle this, it will be greatly appreciated.
Assuming you are using SQLSERVER,you can use Rownumber
;with cte
as
(select pl.PlaceId,
pl.Name,
pop.NumberOfPeople,
pop.Year,
row_number() over(partition by pl.Name order by year desc) as rownum
from dbo.Places pl
inner join dbo.Populations pop
on pop.PlaceId = pl.PlaceId
where pop.NumberOfPeople >= 1000
and pop.NumberOfPeople <= 99999
)
select * from cte where rownum=1
The following query serves the purpose.
CREATE TABLE #TEMP_TEST
(
PlaceId INT,
Name VARCHAR(50),
NumberOfPeople INT,
YEAR INT
)
INSERT INTO #TEMP_TEST
SELECT 1,'Abbeville',2603,2016
UNION
SELECT 5,'Alabester',32948,2016
UNION
SELECT 9,'Aubum',63118,2016
UNION
SELECT 1,'Abbeville',2402,2015
UNION
SELECT 5,'Alabester',67902,2017
SELECT PlaceId, Name, NumberOfPeople, YEAR FROM
(
SELECT ROW_NUMBER() OVER (PARTITION BY PlaceId ORDER BY YEAR DESC) RNO,
PlaceId, Name, NumberOfPeople, YEAR
FROM #TEMP_TEST
)T
WHERE RNO = 1
DROP TABLE #TEMP_TEST
Please help me!! Newby with Sql queries
Select *
from(
select EmpID,
sum(IncomeTax) as TaxAmount,
sum(bsalary) as SalaryAmount
from PayrollHistory Pay
group by EmpID
) cumSalary
Right JOIN (
Select PayrollHistory.EmpID,
(select firstName +' '+coalesce(middleInitial,' ')+' '+ lastName
from Employee
where Employee.EmpID=PayrollHistory.EmpID)as name,
PayrollHistory.IncomeTax,
(PayrollHistory.bsalary+sum(ISNULL(Allw.amount,0)))totalTaxableSUM
from PayrollHistory
left join (
select *
from AllowanceHistory
where AllowanceHistory.taxStatus=1
) as Allw
on Allw.EmpID=PayrollHistory.EmpID and Allw.payMonth=PayrollHistory.payMonth
where PayrollHistory.payMonth=3
group by PayrollHistory.EmpID, PayrollHistory.IncomeTax, PayrollHistory.bsalary
) as tbl
on tbl.EmpID =cumSalary.EmpID
The above query result gives 2 EmpID rows that are the same. How can remove one of them and still get the same result
Instead of first Select * specify all rows that you need like:
select cumSalary.EmpID,
cumSalary.TaxAmount,
cumSalary.SalaryAmount,
tbl.name,
tbl.IncomeTax,
tbl.totalTaxableSUM
etc.
Use column name selection instead of using * , refer as below
Select cumSalary.*,PayrollHistory.name , **....etc** from(
select EmpID, sum(IncomeTax) as TaxAmount,sum(bsalary) as SalaryAmount from
PayrollHistory Pay group by EmpID
) cumSalary
Right JOIN (
Select PayrollHistory.EmpID,(select firstName +' '+coalesce(middleInitial,'
')+' '+ lastName from Employee where
Employee.EmpID=PayrollHistory.EmpID)as name,
PayrollHistory.IncomeTax,( PayrollHistory.bsalary+sum(ISNULL(Allw.amount,0)
))totalTaxableSUM
from PayrollHistory
left join (select * from AllowanceHistory where AllowanceHistory.taxStatus=1
) as Allw on
Allw.EmpID=PayrollHistory.EmpID and Allw.payMonth=PayrollHistory.payMonth
where PayrollHistory.payMonth=3
group by
PayrollHistory.EmpID,PayrollHistory.IncomeTax,PayrollHistory.bsalary
) as tbl on tbl.EmpID =cumSalary.EmpID
I have two table asg and work rship
In work rship table there is date_start for each employee. For few employee date_start is duplicate so I have to choose the min(date_start) from work rship table
for this i wrote a query:
SELECT assignment_name,
REGEXP_SUBSTR(ASSIGNMENT_NAME, '[0-9]+') PERSON_NUMBER,
NVL( wrk.date_start,t.effective_start_date) ,
NVL( WRK.WORKER_TYPE,'E'),
NVL( WRK.LEGAL_EMPLOYER_NAME, 'N/A')
FROM
(SELECT apps.assignment_table.*,
COUNT(*) OVER (PARTITION BY assignment_name, effective_start_date, effective_end_date, effective_latest_change) AS c
FROM apps.assignment_table
) T
LEFT OUTER JOIN
(SELECT *
FROM apps.work_table
WHERE date_start =
(SELECT MIN(date_start) FROM apps.work_table
)
) wrk
ON regexp_substr(t.assignment_name, '[0-9]+')=wrk.person_number
WHERE C =1;
But in the above query I did a mistake of just selecting select min(date_start) from apps.work_table this means min(date_start) from the entire table.
Instead of this I should have included the regexp_substr(t.assignment_name, '[0-9]+')=wrk.person_number inside the inline query itself.
But now when I am including it.. it's not working.
LEFT OUTER JOIN
(SELECT *
FROM apps.work_table
WHERE date_start =
(SELECT MIN(date_start) FROM apps.work_table
)
) wrk
ON
Unless the start_date for the person is the minimum value across all people in the entire table (and not just the minimum date for this person) then the code above will not find any rows that will match the person you want.
What you probably meant to do is something like:
LEFT OUTER JOIN
( SELECT *
FROM (
SELECT t.*,
ROW_NUMBER() OVER ( PARTITION BY person_number ORDER BY date_start ASC ) AS rn
FROM apps.work_table t
)
WHERE rn = 1
) wrk
ON