ROW_NUMBER and Grouping of data - sql

I have a data that looks like this:
What I want is to have a row number that is group by GroupCode,Group Description,SubGroup and subgroup class and I want to retain the ordering by account code that will look like this:
What's the proper way of seting a row number at the same time grouping them?

You are looking for dense_rank():
select dense_rank() over (order by GroupCode, GroupDescription, SubGroup)
. . .
However, this doesn't guarantee the ordering by accountCode. That will require more work. First, determine the minimum account code for each grouping, then use dense_rank() on that:
select t.*, dense_rank() over (order by minac)
from (select t.*,
min(accountCode) over (partition by GroupCode, GroupDescription, SubGroup) as minac
from t
) t

You're looking for the DENSE_RANK window function:
SELECT
rn = DENSE_RANK() OVER(ORDER BY GroupCode, GroupDescription, SubgroupClass),
*
FROM tbl
ORDER BY rn, AccountCode

I Guess you need this
;WITH cte
AS (SELECT groupcode,
groupdescription,
subgroup,
subgroupclass,
Min(accountcode) AS accountcode
FROM your_table
GROUP BY groupcode,
groupdescription,
subgroup,
subgroupclass),
ordr
AS (SELECT Row_number()OVER(ORDER BY accountcode) AS RN,
*
FROM cte)
SELECT C.rn,
A.*
FROM your_table A
INNER JOIN cte C
ON A.groupcode = C.groupcode
AND A.groupdescription = C.groupdescription
AND A.subgroup = C.subgroup
AND A.subgroupclass = C.subgroupclass

Related

How to get maximum continuous iteration

I have a table like below and I need to get maximum continuous iterations for the individual drink.
The output should be like this:
You can try the below - DEMO Here
with cte as (
select drink,count(*) as cnt
from
(
select *,row_number() over(order by queue) -
row_number() over(partition by drink order by queue) as grp
from t
)A group by drink,grp )
select drink, max(cnt) from cte group by drink

Filtering for MAX Beginning Date

I am currently getting the output of the image below. I want to be able to retrieve the latest Turn Time. Essentially the MAX beginning date and MAX end date. How Should I structure my query ?
I think you just want order by:
select top (1) t.*
from t
order by enddate desc, beginning_date desc;
If you want this per id, then you can use window functions or top (1) with ties:
select top (1) t.*
from (select t.*,
row_number() over (partition by id order by enddate desc, beginning_date desc) as seqnum
from t
) t
where seqnum = 1;
You can use row_number()
select * from
(
select *,row_number() over(parition by id order by beginningdate desc) as rn
from tablename
)A where rn=1
For the larger turn time -
select * from
(
select *,row_number() over(parition by id order by turntime desc) as rn
from tablename
)A where rn=1

SQL query to get maximum value for each day

So I have a table that looks something like this:
Now, I want the max totalcst for both days, something like this:
I tried using different variations of max and the Row_number funtion but still can't seem to get the result I want. My query:
select date,pid,max(quan*cst), totalcst
from dbo.test1
group by date, pid
But this returns all the records. So if somebody can point me towards the right direction, that would be very helpful.
Thanks in advance!
ROW_NUMBER should work just fine:
WITH CTE AS
(
SELECT *,
RN = ROW_NUMBER() OVER(PARTITION BY [date] ORDER BY totalcst)
FROM dbo.YourTable
)
SELECT [date],
pid,
totalcst
FROM CTE
WHERE RN = 1
;
Here is one simple way:
select t.*
from test1 t
where t.totalcst = (select max(t2.totalcst) from test1 t2 where t2.date = t.date);
This often has the best performance if you have an index on (date, totalcst). Of course, row_number()/rank() is also a very acceptable solution:
select t.*
from (select t.*, row_number() over (partition by date order by totalcst desc) as seqnum
from test1
) t
where seqnum = 1;

How to use distinct when you select multiple column in SQL

I have use simple inner join statement and getting result into CTE table. I want to select distinct 'ServiceId' from CTE. I have following query
SELECT DISTINCT(ServicesId), ServiceNo, ServiceDate, DealerCode FROM CTE_Temp
Suppose there are duplicate entries of ServiceId in CTE then I want to select first entry only and ignore rest of them.
You can use ROW_NUMBER() OVER() for this. Just replace the column in the ORDER BY to define what's first.
;WITH AnotherCTE AS(
SELECT
ServicesId, ServiceNo, ServiceDate, DealerCode,
RN = ROW_NUMBER() OVER(PARTITION BY ServicesID ORDER BY ServiceDate DESC)
FROM CTE_Temp
)
SELECT
ServicesId, ServiceNo, ServiceDate, DealerCode
FROM AnotherCTE
WHERE RN = 1

How to get the row that holds the last value in a queue of identical values? (SQL)

I think it's easier to show you an image:
So, for each fld_call_id, go to the next value, if it's identical. When we get to the last value, I need the value in column fld_menu_id.
Or, to put it in another way, eliminate fld_call_id duplicates and save only the last one.
You can use ROW_NUMBER:
WITH CTE AS(
SELECT RN = ROW_NUMBER() OVER (PARTITION BY fld_call_id ORDER BY fld_id DESC),
fld_menu_id
FROM dbo.TableName
)
SELECT fld_menu_id FROM CTE WHERE RN = 1
You can create a Rank column and only select that row, something along the lines of the following:
;WITH cte AS
(
SELECT
*
,RANK() OVER (PARTITION BY fld_call_id ORDER BY fld_id DESC) Rnk
FROM YourTable
)
SELECT
*
FROM cte
WHERE Rnk=1
So you GROUP BY fld_call_id and ORDER BY fld_id in descending order so that the last value comes first. These are the rows where Rnk=1.
Edit after comments of OP.
SELECT Table.*
FROM Table
INNER JOIN
(
SELECT MAX(fldMenuID) AS fldMenuID,
fldCallID
FROM Table
GROUP BY fldCallID
) maxValues
ON (maxValues.fldMenuID = Table.fldMenuID
AND maxValues.fldCallID= Table.fldCallID)
Hope This works
SELECT A.*
FROM table A
JOIN (SELECT fld_id,
ROW_NUMBER() OVER (PARTITION BY Fld_call_id ORDER BY fld_id DESC) [Row]
FROM table) LU ON A.fld_id = LU.fld_id
WHERE LU.[Row] = 1