How to extract the latest created row for each group? - sql-server

I Have a table below and I would like to group the data by Opportunity_Id and pick up the rows with latest CreatedDate for each Opportunity_Id. I use local variable and table type to load in case by case. Is there any other more effienct way like using a set of query only to achieve the same result? Thanks heaps

SELECT *
FROM (
SELECT *,
row_number() over (partition by opportunity_id
order by Created_Date desc) rn
FROM yourTable
) T
WHERE T.rn = 1

Related

SQL Server - How to set Row ID for duplicate or similar content based on insertion first. Select query

Priority is the output column.
The group contains duplicate content.
how can I fix this using SQL query?.
enter image description here
One way to achieve the desired result with this data is to use Dense_rank() function like below:
select *, dense_rank() over (order by [Group]) as Priority
from tab
order by No
For any value, please try the following
;with cte as
(
select [Group], ROW_NUMBER() over (order by No_min) as rn
from
(
select [Group], min([No]) No_min
from tab
group by [Group]
)t
)
select t.*, x.rn as [Priority]
from cte x
join tab t on t.[Group] = x.[Group]
order by 1
Please find the db<>fiddle here.

How can I get only last run of each SSIS job using T-SQL query?

How can I get only the last run of each SSIS job using a T-SQL query?
Please check the image. These details are stored in a single Table XYZ. Can anyone help me by providing a T-SQL query?
I am using this query:
select Job_Name, Start_Date, Finish_Time, Remarks
from #XYZ
order by Job_Name
You can use row_number()
select x.*
from (select x.*,
row_number() over (partition by job_name order by try_convert(datetime, Finish_Time) desc) as seq
from #XYZ x
) x
where x.seq = 1;
You can do this by adding a row_number to sort the data and then filtering to where a 1 is returned:
select cols
from(select cols
,row_number() over (partition by Job_Name order by Start_Date desc) as rn
from table
) as t
where rn = 1

Column 'ACCOUNT.ACCOUNT_ID' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause

I am trying to get available balance on last(max) date. I am trying to write below query but it is showing error.
select ACCOUNT_ID,AVAIL_BALANCE,OPEN_DATE,MAX(LAST_ACTIVITY_DATE)
from ACCOUNT
group by CUST_ID;
Column 'ACCOUNT.ACCOUNT_ID' is invalid in the select list because it
is not contained in either an aggregate function or the GROUP BY
clause.
I am new to sql. Can anyone let me know where I am wrong in this query?
Any column not having a calculation/function on it must be in the GROUP BY clause.
select ACCOUNT_ID,AVAIL_BALANCE,OPEN_DATE,MAX(LAST_ACTIVITY_DATE)
from ACCOUNT
group by ACCOUNT_ID,AVAIL_BALANCE,OPEN_DATE;
If you're wanting the most recent row for each customer, think ROW_NUMBER(), not GROUP BY:
;With Numbered as (
select *,ROW_NUMBER() OVER (
PARTITION BY CUST_ID
ORDER BY LAST_ACTIVITY_DATE desc) rn
from Account
)
select ACCOUNT_ID,AVAIL_BALANCE,OPEN_DATE,LAST_ACTIVITY_DATE
from Numbered
where rn=1
I think you want to select one records having max(LAST_ACTIVITY_DATE) for each CUST_ID.
For this you can use TOP 1 WITH TIES like following.
SELECT TOP 1 WITH TIES account_id,
avail_balance,
open_date,
last_activity_date
FROM account
ORDER BY Row_number()
OVER (
partition BY cust_id
ORDER BY last_activity_date DESC)
Issue with your query is, you can't select non aggregated column in select if you don't specify those columns in group by
If you want to get the max activity date for a customer then your query should be as below
select CUST_ID, MAX(LAST_ACTIVITY_DATE)
from ACCOUNT
group by CUST_ID;
You can't select any other column which is not in the group by clause. The error message also giving the same message.
with query(CUST_ID, LAST_ACTIVITY_DATE) as
(
select
CUST_ID,
MAX(LAST_ACTIVITY_DATE) as LAST_ACTIVITY_DATE
from ACCOUNT
group by CUST_ID
)
select
a.ACCOUNT_ID,
a.AVAIL_BALANCE,
a.OPEN_DATE,
a.LAST_ACTIVITY_DATE
from ACCOUNT as a
inner join query as q
on a.CUST_ID = q.CUST_ID
and a.LAST_ACTIVITY_DATE = q.LAST_ACTIVITY_DATE

Determining Percentile Difference from lag, lead and current row using windows function?

Is there a better way to get the moving percentile using a windows function without utilizing a CTE or derived table etc? I wanted to fit it all in one query utilizing windows functions, but im having a hell of a time converting it to a percentile value. The only resolution I could think of was to create the numeric values and then do the math with the table. Just would be cool if there was a more streamlined way to do this?
WITH numberdata AS
(
SELECT
custid
,orderid
,LAG(VAL) OVER(PARTITION BY CUSTID ORDER BY ORDERID DESC) as lagval
,LEAD(VAL) OVER(PARTITION BY CUSTID ORDER BY ORDERID DESC) as leadval
,val - LAG(VAL) OVER(PARTITION BY CUSTID ORDER BY ORDERID DESC) as lagvaldiff
,val - LEAD(VAL) OVER(PARTITION BY CUSTID ORDER BY ORDERID DESC) as leadvaldiff
,val
FROM sales.ordervalues
)
select
CAST((lagval)/val AS NUMERIC(10,2)) as lagpctdiff
,CAST((leadval)/val AS NUMERIC(10,2)) as leadpctdiff
,CAST((lagvaldiff)/leadvaldiff AS NUMERIC(10,2)) as pctdiff
,val
,lagval
from numberdata
order by custid desc
This is just me studying to learn more about the code in preparation of a test. Data comes from the sales.ordervalues table located in training db TSQL_2012.
How can I convert the leadvaldiff and lagvaldiff columns to a percentage without placing it within a CTE?
dataset
Am i missing something or is this what you are looking for?
SELECT LAG(VAL) OVER(PARTITION BY CUSTID ORDER BY ORDERID DESC)/val as lagval
,LEAD(VAL) OVER(PARTITION BY CUSTID ORDER BY ORDERID DESC)/val as leadval
,(val - LAG(VAL) OVER(PARTITION BY CUSTID ORDER BY ORDERID DESC))/
(val - LEAD(VAL) OVER(PARTITION BY CUSTID ORDER BY ORDERID DESC)) as pctdiff
FROM sales.OrderValues;

cannot use alias in ROW_NUMBER() over in SQL Server?

I have to create a row_number column ordered by a grouped sum, when using sql:
select Sales.Name, SUM(Sales.Bill) as billsum, ROW_NUMBER() over (order by billsum DESC) as rn
from Sales group by Sales.Name
It reports error because row_number over cannot parse the "billsum" alias, I have to write:
select Sales.Name, SUM(Sales.Bill) as billsum, ROW_NUMBER() over (order by SUM(Sales.Bill) DESC) as rn
from Sales group by Sales.Name
so here I write SUM(Sales.Bill) twice, is there anyway to use the alias here?
The MSDN docs for the T-SQL OVER clause say:
value_expression cannot refer to expressions or aliases in the select list.
As already stated out by other member you either have to use CTE or SubQuery.
Not only Row_Number() function but in tsql you can not reference alias in same query, so either you have to use one of the mentioned way above or the expression you used in your post. I hope it makes sense!! :)
Possible work-arounds are to use CTE or a subquery:
SELECT Name, billsum, ROW_NUMBER() OVER (ORDER BY billsum DESC) AS rn
FROM
( SELECT Sales.Name, SUM(Sales.Bill) AS billsum
FROM Sales
GROUP BY Sales.Name
) tmp
-- Reorder after cutting out qty = 0.
SELECT *,ROW_NUMBER() OVER (partition by claimno ORDER BY itemno) as 'alias name'
from dbo.OrderCol
where QTY <> 0

Resources