Trouble using ROW_NUMBER() OVER (PARTITION BY - sql

I have this query :
SELECT
Reservation.*,
ROW_NUMBER() OVER (PARTITION BY code_bien ORDER BY (SELECT NULL)) AS RowNums
FROM
Reservation
WHERE
RowNums = 1
I get this error :
Msg 207, Level 16, State 1, Line 2
Invalid column name 'RowNums'.
I don't know where the problem is - any help?

You'd need to use a CTE:
WITH tempData AS
(
SELECT Reservation.*,
ROW_NUMBER() OVER (PARTITION BY code_bien ORDER BY (SELECT NULL)) AS RowNums
FROM Reservation
)
SELECT * FROM tempData WHERE RowNums = 1
However, a cleaner approach would be to use WITH TIES:
SELECT TOP 1 WITH TIES *
FROM Reservation
ORDER BY ROW_NUMBER() OVER (PARTITION BY code_bien ORDER BY (SELECT NULL))

You can't use RowNums directly,
Try like this,
SELECT *
FROM
(
SELECT Reservation.*,ROW_NUMBER() OVER (PARTITION BY code_bien ORDER BY (SELECT NULL)) AS RowNums
FROM Reservation
) S
where RowNums = 1

SELECT t.*
FROM
(SELECT Reservation.*,ROW_NUMBER() OVER (PARTITION BY code_bien ORDER BY NULL ) AS RowNums
FROM Reservation) t
where RowNums = 1

You cannot use this directly as this is not a column in the table. Either use CTE or derived table.
CTE
:WITH C AS (
SELECT Reservation.*,ROW_NUMBER() OVER (PARTITION BY code_bien ORDER BY (SELECT NULL)) AS RowNums
)
SELECT * FROM C WHERE RowNums = 1

Try this
;WITH CTE AS(
SELECT Reservation.*,
ROW_NUMBER() OVER (PARTITION BY code_bien ORDER BY (SELECT NULL)) AS RowNums
FROM Reservation)
SELECT * FROM CTE
WHERE RowNums = 1

Related

Creating column and filtering it in one select statement

Wondering if it is possible to creating a new column and filter on that column. The following is an example:
SELECT row_number() over (partition by ID order by date asc) row# FROM table1 where row# = 1
Thanks!
Some databases support a QUALIFY clause which you might be able to use:
SELECT *
FROM table1
QUALIFY ROW_NUMBER() OVER (PARTITION BY ID ORDER BY date) = 1;
On SQL Server, you may use a TOP 1 WITH TIES trick:
SELECT TOP 1 WITH TIES *
FROM table1
ORDER BY ROW_NUMBER() OVER (PARTITION BY ID ORDER BY date);
More generally, you would have to use a subquery:
WITH cte AS (
SELECT t.*, ROW_NUMBER() OVER (PARTITION BY ID ORDER BY date) rn
FROM table1 t
)
SELECT *
FROM cte
WHERE rn = 1;
The WHERE clause is evaluated before the SELECT so your column has to exist before you can use a WHERE clause. You could achieve this by making a subquery of the original query.
SELECT *
FROM
(
SELECT row_number() over (partition by ID order by date asc) row#
FROM table1
) a
WHERE a.row# = 1

SQL command for getting a specific pattern

I have a table sample with column 'observations':
Please help with the SQL command to get the following 'cumulative multiplication' output:
2
6
30
300
One method is a recursive CTE:
with tt as (
select t.*, row_number() over (order by obs) as seqnum
from t
),
cte as (
select obs as prod, seqnum
from tt
where seqnum = 1
union all
select cte.prod * tt.obs, tt.seqnum
from cte join
tt
on tt.seqnum = cte.seqnum + 1
)
select *
from cte;
Another uses arithmetic to implement a "product" window function:
select t.*,
exp(sum(log(obs)) over (order by obs))
from t;
Here is a db<>fiddle.

How to get MAX rownumber with rowNumber in same query

I have ROW_NUMBER() OVER (ORDER BY NULL) rnum in a sql statement to give me row numbers. is there a way to attach the max rnum to the same dataset going out?
what I want is the row_number() which I get, but I also want the MAXIMUM rownumber of the total return on each record.
SELECT
ROW_NUMBER() OVER (ORDER BY NULL) rnum,
C.ID, C.FIELD1, C."NAME", C.FIELD2, C.FIELD3
FROM SCHEMA.TABLE
WHERE (C.IS_CRNT = 1)
), MAX_NUM as (
SELECT DATA.ID, max(rnum) as maxrnum from DATA GROUP BY DATA.COMPONENT_ID
) select maxrnum, DATA.* from DATA JOIN MAX_NUM on DATA.COMPONENT_ID = MAX_NUM.COMPONENT_ID
DESIRED RESULT (ASSUMING 15 records):
1 15 DATA
2 15 DATA
3 15 DATA
etc...
I think you want count(*) as a window function:
SELECT ROW_NUMBER() OVER (ORDER BY NULL) as rnum,
COUNT(*) OVER () as cnt,
C.ID, C.FIELD1, C."NAME", C.FIELD2, C.FIELD3
FROM SCHEMA.TABLE
WHERE C.IS_CRNT = 1
Based on my assumptions in your dataset, this is the approach I would take:
WITH CTE AS (
select C.ID, C.FIELD1, C."NAME", C.FIELD2, C.FIELD3, ROW_NUMBER() OVER (PARTITION BY ID ORDER BY ID)
FROM SCHEMA.TABLE WHERE (C.IS_CRNT = 1))
SELECT *, (select count(*) from cte) "count" from cte;

SQL Server ROW_NUMBER() Issue

I'm using row_number() expression but I don't get result as I expected. I have a sql table and some rows are duplicate. They have same 'BATCHID' and I want to get second row number for these, for others I use first row number. How can I do it?
SELECT * FROM (SELECT * , ROW_NUMBER() OVER (PARTITION BY BATCHID ORDER BY SCAQTY) Rn FROM SAYIMDCPC ) t
WHERE Rn=1
This code returns to me only first rows, but I want to get second rows for duplicated items.
ROW_NUMBER() gives every row a unique counter. You'd want to use RANK(), which is similar, but gives rows with identical values the same score:
SELECT *
FROM (SELECT * , RANK() OVER (PARTITION BY batchid ORDER BY scaqry) rk
FROM sayimdcpc) t
WHERE rk = 1
If some values are only shown once, but some twice (and perhaps more than twice), you don't want the "first" row, you want the "max" row. Try reversing your order condition:
SELECT *
FROM (SELECT * ,
ROW_NUMBER() OVER (PARTITION BY BATCHID ORDER BY SCAQTY DESC) Rn
FROM SAYIMDCPC ) t
WHERE Rn=1
As a side note, it's still better to explicitly list out all columns; for instance, you probably don't need Rn outside of this query...
Simply try this,
SELECT * FROM (SELECT * , ROW_NUMBER() OVER (ORDER BY SCAQTY) Rn FROM SAYIMDCPC ) t
WHERE Rn=1
To rephrase it another way, it sounds like you're saying, "When there's a single row for the Batch ID, return the single row. When there are 2 or more rows, return the second row." That's going to require inspecting your Rn value to see what its max is. I don't think you can do it in a single query.
So I'd try something like this:
WITH NumberedRows AS (
SELECT * ,
ROW_NUMBER() OVER (PARTITION BY BATCHID ORDER BY SCAQTY) Rn
FROM SAYIMDCPC
)
, MaxNumber AS (
SELECT Max(RN) as MaxRn,
BATCHID
FROM NumberedRows
GROUP BY BATCHID
)
, NonDupes AS (
SELECT *
FROM NumberedRows
WHERE BATCHID NOT IN (SELECT BATCHID FROM MaxNumber WHERE MaxNumber = 1)
)
, SecondRows AS (
SELECT (
FROM NumberedRows
WHERE BATCHID NOT IN (SELECT BATCHID FROM MaxNumber WHERE MaxNumber > 1)
AND Rn = 2
)
SELECT
FROM NonDupes
UNION ALL
SELECT *
FROM SecondRows
Please try this. It will select max row num, if no duplicate then it should be first one otherwise second
select * from (SELECT * , ROW_NUMBER() OVER (PARTITION BY BATCHID ORDER BY SCAQTY) Rn FROM SAYIMDCPC ) d,
(SELECT batchid,max(Rn) maxRn FROM (SELECT * , ROW_NUMBER() OVER (PARTITION BY BATCHID ORDER BY SCAQTY) Rn FROM SAYIMDCPC ) t
group by batchid) q
where d.batchid = q.batchid and d.rn = q.maxrn
correct me if i am wrong
e.g sample data
BatchID, SCAQTY
1 , 10
2 , 10
2 , 20
2 , 30
is your expectation result like below?
**Expectation Result 1**
BatchID , SCAQty
1 , 10
2 , 30
or
**Expectation Result 2**
BatchID , SCAQty
1 , 10
2 , 20
2 , 30
based on my understanding what you want to perform is Expectation Result 1, so i guess Query below should able to help u, you just need to add desc for SCAQTY in your query
SELECT * FROM (SELECT * ,
ROW_NUMBER() OVER (PARTITION BY BATCHID ORDER BY SCAQTY DESC) Rn FROM SAYIMDCPC ) t
WHERE Rn=1
Total result set with duplicates and non duplicates. The first column "IsDuplicate" indicates if the column is a duplicate or not.
;WITH d1 AS (
SELECT Seq = ROW_NUMBER() OVER (PARTITION BY BATCHID ORDER BY SCAQTY)
,*
FROM SAYIMDCPC
)
SELECT IsDuplicate = CONVERT(BIT, Seq)
,*
FROM d1
This will give you only the duplicates:
;WITH d1 AS (
SELECT Seq = ROW_NUMBER() OVER (PARTITION BY BATCHID ORDER BY SCAQTY)
,*
FROM SAYIMDCPC
)
SELECT IsDuplicate = CONVERT(BIT, Seq)
,*
FROM d1
WHERE Seq > 1
This will give you only the non duplicates (as in your first query)
;WITH d1 AS (
SELECT Seq = ROW_NUMBER() OVER (PARTITION BY BATCHID ORDER BY SCAQTY)
,*
FROM SAYIMDCPC
)
SELECT IsDuplicate = CONVERT(BIT, Seq)
,*
FROM d1
WHERE Seq = 1

How do I create a temp table using this snippet?

how do i produce this SQL snippet as a temp table so I can join some other stuff into it?
with MyCTE AS
(
select *, RANK() OVER (PARTITION BY workplace ORDER BY Total DESC) AS Rank
from [dbo].[OriginDestination]
)
select * from MyCTE where Rank <= 5
Like this:
with MyCTE AS
(
select *, RANK() OVER (PARTITION BY workplace ORDER BY Total DESC) AS Rank
from [dbo].[OriginDestination]
)
select *
into #yourTempTable
from MyCTE
where Rank <= 5