T-SQL Group skip and take - sql-server

Consider following tables:
How to skip and take groups from the table? Tried using Row_Number() but it doesn't help. Any ideas?
Used query
;WITH cte AS (SELECT Room.Id, Room.RoomName,
ROW_NUMBER() OVER
(ORDER BY Room.Id) AS RN
FROM Room INNER JOIN
RoomDetails ON Room.Id = RoomDetails.RoomId)
SELECT Id, RoomName
FROM cte
WHERE RN = 1

You need to use partition as part of the dense_rank function
dense_rank() over (partition by roomid) as row
see here for some more examples Windowing functions

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.

SQL ORDER BY clause ERROR in the ROW_NUMBER

I want to use ROW_NUMBER() function and get first and latest values.
I write bellow query. But I got an error.
The ORDER BY clause is invalid in views, inline functions, derived tables, subqueries, and common table expressions, unless TOP, OFFSET or FOR XML is also specified.
help me to solve the issue. Below the sql query
SELECT *
FROM(
SELECT OPP_ID,PRJ_ID,
ROW_NUMBER() OVER (PARTITION BY OPP_ID ORDER BY MAX(CREATION_DATE) DESC) AS RN
FROM OPPOR
GROUP BY OPP_ID,PRJ_ID
ORDER BY MAX(CREATION_DATE) DESC) OP
WHERE OP.RN = 1
The row_number function can do it's own aggregation and ordering, so no need to use group by or order by in your subquery (order by won't work in subqueries as you've seen). It is a little unclear if you want to partition by opp_id or opp_id and prj_id though. But this should be what you're looking for:
SELECT *
FROM(
SELECT OPP_ID,PRJ_ID,
ROW_NUMBER() OVER (PARTITION BY OPP_ID ORDER BY CREATION_DATE DESC) AS RN
FROM OPPOR
) OP
WHERE OP.RN = 1

StackExchange Query Help t-sql

Would anybody be able to help me with this exercise. I am used to querying on postgresql and not t-sql and I am running into trouble with how some of my data aggregates
My assignment requires me to:
Create a query that returns the number of comments made on each day for each post from the top 50 most commented on posts in the past year.
For example, this query below is giving me a non aggregated result set:
select cast(creationdate as date),
postid,
count(id)
from comments
where postid = 17654496
group by creationdate, postid
The schema is all here
https://data.stackexchange.com/stackoverflow/query/edit/898297
You can try to use CTE get the count by date.
then use window function with ROW_NUMBER make row number order by count amount desc.
;with CTE as (
select cast(creationdate as date) dt,
postid,
count(id) cnt
from comments
WHERE creationdate between dateadd(year,-1,getdate()) and getdate()
group by cast(creationdate as date), postid
), CTE2 AS (
select *,ROW_NUMBER() OVER (order by cnt desc) rn
from CTE
)
SELECT *
FROM CTE2
WHERE rn <=50
https://data.stackexchange.com/stackoverflow/query/898322/test

Get the id of the row with the max value with two grouping

We have a data structure with four columns:
ContractoreName, ProjectCode, InvoiceID, OrderID
We want to group the data by both ContractoreName and ProjectCode columns, and then get the InvoiceID of the row for each group with MAX(OrderID).
You could use ROW_NUMBER:
SELECT ContractorName, ProjectName, OrderId, InvoiceId
FROM (SELECT *, ROW_NUMBER() OVER(PARTITION BY ContractorName, ProjectName
ORDER BY OrderId DESC) AS rn
FROM tab
) AS sub
WHERE rn = 1;
ROW_NUMBER() is what I would call the canonical solution. In many cases, an old-fashioned solution has better performance:
select t.*
from t
where t.orderid = (select max(t2.orderid)
from t t2
where t2.contractorname = t.contractorname and
t2.projectname = t.projectname
);
This is especially true if there is an index on (contractorname, projectname, orderid).
Why is this faster? Basically, SQL Server can scan the table doing a lookup in an index. The lookup is really fast because the index is designed for it, so the scan is just a little faster than a full table scan.
When using row_number(), SQL Server has to scan the table to calculate the row number (and that can use the index, so it might be fast). But then it has to go back to the table to fetch the columns and apply the where clause. So, even if it uses an index, it is doing more work.
EDIT:
I should also point out that this can be done without a subquery:
select distinct contractorname, projectname,
max(orderid) over (partition by contractorname, projectname) as lastest_order,
first_value(invoiceid) partition by (order by contractorname, projectname order by orderid desc) as lastest_invoice
from t;
Unfortunately, SQL Server doesn't offer first_value() as an aggregation function, but you can use select distinct and get the same effect.

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