T-SQL: Update first row of recordset - sql

I have a query (A) that can returns multiple rows in date order:
SELECT encounter_id, department_id, effective_time
FROM adt
WHERE event_type IN (1,3,7)
ORDER BY effective_time
I have another query (B) that returns a single row:
SELECT encounter_id, department_id, arrival_time
FROM ed
WHERE event_type = 50
I would like to join the query B to query A, in such a way that query B's single row will be associated with query A's first record.
I realize that I could do this with a CURSOR, but I was hoping to use T-SQL row_number() function.

Not sure if i got the question right.
Let me know if the below solution is different than what you were expecting
SELECT *
FROM
(
SELECT TOP 1
encounter_id, department_id, effective_time
FROM adt
WHERE event_type IN (1,3,7)
ORDER BY effective_time
)adt1,
(
SELECT encounter_id, department_id, arrival_time
FROM ed
WHERE event_type = 50
) ed1
then you can join both the tables as per your need, using WHERE clause
Regards,
Niyaz

I found my answer:
row_number() OVER (PARTITION BY encounter_id ORDER BY encounter_id, effective_time) row.
Unfortunately, the database has data-quality issues that prevent me from approaching the solution this way.
Thanks for your assistance.

Related

how to get latest date column records when result should be filtered with unique column name in sql?

I have table as below:
I want write a sql query to get output as below:
the query should select all the records from the table but, when multiple records have same Id column value then it should take only one record having latest Date.
E.g., Here Rudolf id 1211 is present three times in input---in output only one Rudolf record having date 06-12-2010 is selected. same thing with James.
I tried to write a query but it was not succssful. So, please help me to form a query string in sql.
Thanks in advance
You can partition your data over Date Desc and get the first row of each partition
SELECT A.Id, A.Name, A.Place, A.Date FROM (
SELECT
*,
ROW_NUMBER() OVER (PARTITION BY Id ORDER BY Date DESC) AS rn
FROM [Table]
) A WHERE A.rn = 1
you can use WITH TIES
select top 1 PERCENT WITH TIES * from t
order by (row_number() over(partition by id order by date desc))
https://dbfiddle.uk/?rdbms=sqlserver_2017&fiddle=280b7412b5c0c04c208f2914b44c7ce3
As i can see from your example, duplicate rows differ only in Date. If it's a case, then simple GROUP BY with MAX aggregate function will do the job for you.
SELECT Id, Name, Place, MAX(Date)
FROM [TABLE_NAME]
GROUP BY Id, Name, Place
Here is working example: http://sqlfiddle.com/#!18/7025e/2

SQL: select max values from two related tables

I have tables: Waiter and WaiterDetail and Cafe. Cafe can have many Waiters and Waiter may have many WaiterDetails. I would like to find oldest WaiterDetail by field CreatedDate, of the first hired Waiter by his HiredDate.
Cafe:
*CafeId(primary)
Waiter:
*WaiterId(primary)
*CafeId
*HiredDate
WaiterDetail:
*WaiterDetailID(primary)
*WaiterId
*CreatedDate
How will look like query for Oracle and MS SQL Server?
If I have it correct, you want: for each Cafe to find Waiter with the first (earliest) HiredDate and, for that waiter, find detail with the oldest (earliest) CreatedDate. So, for Oracle (and maybe SQL Server), something like this:
SELECT *
FROM (
SELECT w.*,
d.*,
ROW_NUMBER() OVER ( PARTITION BY CafeID
ORDER BY w.HiredDate ASC,
d.CreatedDate ASC ) AS rn
FROM Waiter w
INNER JOIN WaiterDetail d
ON ( w.WaiterId = d.WaiterId )
)
WHERE rn = 1;

Implement FIRST() in select and not in WHERE

I want to get first value in a field in Oracle when another corresponding field has max value.
Normally, we would do this using a query and a subquery. The subquery ordering by a field and the outer query with where rownum<=1.
But, I cannot do this because the table aliases persist only one level deep and this query is a part of another big query and I need to use some aliases from the outermost query.
Here's the query structure
select
(
select a --This should get first value of a after b's are sorted desc
from
(
select a,b from table1 where table1.ID=t2.ID order by b desc
)
where rownum<=1
)
) as "A",
ID
from
table2 t2
Now this is not gonna work because alias t2 wont be available at innermost query.
Real world analogy that comes to my mind is I have a table containing records for all employees of a company, their salaries(including past salaries) and the date from which the salary was effective. So, for each employee, there will multiple records. Now, I want to get latest salaries for all the employees.
With SQL server, I could have used SELECT TOP. But that's not available with Oracle and since where clauses execute before order by, I cannot use where rownum<=1 and order by in same query and expect correct results.
How do I do this?
Using your analogy of employees and their salaries, if I understand what you are trying to do, you could do something like this (haven't tested):
SELECT *
FROM (
SELECT employee_id,
salary,
effective_date,
ROW_NUMBER() OVER (PARTITION BY employee_id ORDER BY effective_date DESC) rowno
FROM employees
)
WHERE rowno=1
I would much rather see you connect the subquery up with a JOIN instead of embedding it in the SELECT. Cleaner SQL. Then you can use the windowing function that roartechs suggests.
Select t2.whatever, t1.a
From table2 t2
Inner Join (
Select tfirst.ID, tfirst.a
From (
Select ID, a,
ROW_NUMBER() Over (Partition BY ID ORDER BY b DESC) rownumber
FROM table1
) tfirst
WHERE tfirst.rownumber=1
) t1 on t2.ID=t1.ID

How to get the MAX result even if the MAX is different

I have a code where I am pulling language knowledge and each employee has a plan year, they do not all complete them each year and in order to get their most recent one I use the MAX for plan year. Now one of the criteria is whether or not they are willing to move over seas, the issue arises that it will bring up their most recent YES and most recent NO and I just need their most recent plan year whether it be yes or no, I am having difficulty troubleshooting this. The code is as follows:
SELECT Employee_ID, Accept_International_Assignment, MAX(Plan_Year) AS Expr1
FROM dbo.v_sc08_CD_Employee_Availabilities
GROUP BY Employee_ID, Accept_International_Assignment
I suspect this will be more efficient than the accepted answer, at scale...
;WITH x AS
(
SELECT Employee_ID, Accept_International_Assignment, Plan_Year,
rn = ROW_NUMBER() OVER (PARTITION BY Employee_ID ORDER BY Plan_Year DESC)
FROM dbo.v_sc08_CD_Employee_Availabilities -- who comes up with these names?
)
SELECT Employee_ID, Accept_International_Assignment, Plan_Year
FROM x WHERE rn = 1;
SELECT a.Employee_ID, a.Accept_International_Assignment, a.Plan_Year
FROM dbo.v_sc08_CD_Employee_Availabilities a
INNER JOIN (SELECT Employee_ID, MAX(Plan_Year) maxPlanYear
from dbo.v_sc08_CD_Employee_Availabilities
GROUP BY Employee_ID) m
ON a.Plan_Year = m.maxPlanYear AND a.Employee_ID = m.Employee_ID
I'm not sure if you want only the most recent decision and year as Raphael posted or if you want the yes's and the no's but always with the Max plan year for that employee.
Here is a query for the yes's and no's but Max plan year is always the max for the employee.
select main.Employee_ID, Accept_International_Assignment, Expr1
from (
SELECT Employee_ID, Accept_International_Assignment
FROM #v_sc08_CD_Employee_Availabilities
GROUP BY Employee_ID, Accept_International_Assignment
) main
inner join
(
select Employee_ID, MAX(Plan_Year) as Expr1
from #v_sc08_CD_Employee_Availabilities
group by Employee_ID) empPlanYear
on main.Employee_ID = empPlanYear.Employee_ID
You need a subquery on the max() and join against that.
SQL Group by & Max

Over clause in SQL Server

I have the following query
select * from
(
SELECT distinct
rx.patid
,rx.fillDate
,rx.scriptEndDate
,MAX(datediff(day, rx.filldate, rx.scriptenddate)) AS longestScript
,rx.drugClass
,COUNT(rx.drugName) over(partition by rx.patid,rx.fillDate,rx.drugclass) as distinctFamilies
FROM [I 3 SCI control].dbo.rx
where rx.drugClass in ('h3a','h6h','h4b','h2f','h2s','j7c','h2e')
GROUP BY rx.patid, rx.fillDate, rx.scriptEndDate,rx.drugName,rx.drugClass
) r
order by distinctFamilies desc
which produces results that look like
This should mean that between the two dates in the table the patID that there should be 5 unique drug names. However, when I run the following query:
select distinct *
from rx
where patid = 1358801781 and fillDate between '2008-10-17' and '2008-11-16' and drugClass='H4B'
I have a result set returned that looks like
You can see that while there are in fact five rows returned for the second query between the dates of 2008-10-17 and 2009-01-15, there are only three unique names. I've tried various ways of modifying the over clause, all with different levels of non-success. How can I alter my query so that I only find unique drugNames within the timeframe specified for each row?
Taking a shot at it:
SELECT DISTINCT
patid,
fillDate,
scriptEndDate,
MAX(DATEDIFF(day, fillDate, scriptEndDate)) AS longestScript,
drugClass,
MAX(rn) OVER(PARTITION BY patid, fillDate, drugClass) as distinctFamilies
FROM (
SELECT patid, fillDate, scriptEndDate, drugClass,rx.drugName,
DENSE_RANK() OVER(PARTITION BY patid, fillDate, drugClass ORDER BY drugName) as rn
FROM [I 3 SCI control].dbo.rx
WHERE drugClass IN ('h3a','h6h','h4b','h2f','h2s','j7c','h2e')
)x
GROUP BY x.patid, x.fillDate, x.scriptEndDate,x.drugName,x.drugClass,x.rn
ORDER BY distinctFamilies DESC
Not sure if DISTINCT is really necessary - left it in since you've used it.