Parameters for fetch first rows in query - sql

I have the following query:
WITH lftno(counterrow) AS (
VALUES(select rownos
from test.table1
where year='2020' and usage='1')
)
UPDATE test.deltable
SET year=concat('31.12.','2012')
WHERE ID IN (
select res.id
from (
select res.id
from (
SELECT ROW_NUMBER() OVER (ORDER BY year ASC) AS delyear
, ID, year
from test.deltable
) res
where year(res.year)='2012'
fetch first integer(counterrow) rows only
)
The result of the with select is 10 so I want the fetch first line to use that 10 as the value for the rows to catch.
The final query is a lot longer but to show the problem this is easy for readablity.
I tried
'fetch first ' || integer(counterrow) || ' rows only'
or as part of the where clause
AND row_number() over() <= counterrow
but that didn't work either.
The point is that I can not resort them with an over part. I just need the lines as given by the counterrow.
Any ideas?
Thanks for you help.

You can't use row_number() in a WHERE clause. And, the FETCH clause requires constants. But, you can use the row_number() in a subquery and use the result in the outer query. If I understand correctly, you want:
WITH lftno(counterrow) AS (
VALUES(select rownos from test.table1 where year = '2020' and usage = '1')
)
select res.id
from (SELECT ROW_NUMBER() OVER (ORDER BY year ASC) AS delyear,
ID, year
from test.deltable
) res
where year(res.year) = '2012' and
delyear <= counterrow;

Related

Select only one record where information is fully provided and/or the lowest value in it (SQL) [duplicate]

This question already has answers here:
Get top 1 row of each group
(19 answers)
Closed 10 months ago.
I have such a situation. I need to make a code work so that it selects only one PVISBN (Item Number) based on PVLICP (license plate) (I need to get only the first row from 2 that I am getting back).
TableSeven AS (
SELECT PVISBN, PVWHS, PVLICP, PVRZNE, PVRLOC, PVAZNE, PVALOC, PVLPRG,
ROW_NUMBER() OVER (PARTITION BY PVISBN, PVRZNE ORDER BY PVLICP --, PVRLOC, PVAZNE, PVALOC, PVLPRG
ASC) AS rn
FROM [REPIT].[LEVYDTA].[WHSPDVT]
WHERE PVSPDT BETWEEN #Last2WeekDATE AND #LWDate
--AND PVISBN='0164556221'
) ,
TableTwelve AS (
SELECT PVISBN, PVWHS, PVLICP, PVRZNE, PVRLOC, PVAZNE, PVALOC, PVLPRG, rn
FROM TableSeven
WHERE rn = 1
),
I keep getting 2 rows and should get only the 1st one
If someone may have an idea, I will appreciate.
Assuming "Oldest" and "Lowest" is the same, you can use aggregation:
SELECT PVISBN, MIN(PVLICP) as PVLICP
FROM yourtable
GROUP BY PVISBN;
To your comment, if you are wanting all columns in the output, then consider window functions (also called Analytics Functions or Ordered Analytics Functions) to help identify the min() for a group/window (PVISBN in this case) and then filter:
SELECT *
FROM
(
SELECT yourtable.*, ROW_NUMBER() OVER (PARTITION BY PVISBN ORDER BY PVLICP ASC) as rn
FROM yourtable
) dt
WHERE rn = 1;
That will generate a row_number, starting at 1 for each row for each distinct PVISBN (you can run just the subquery to see how that looks). Then we just filter for rn of 1, which will be the record for that PVISBN with the lowest PVLICP.
I think this would be helpful for you
SELECT PVISBN, PVWHS, MIN(PVLICP) as PVLICP , ------------ FROM tablename WHERE PVLICP IS NOT NULL or PVLICP <> '' group by PVISBN;

Need help in using LISTAGG function with DISTINCT

Select ID,
LISTAGG(DISTINCT VIEW_NM, ',') WITHIN GROUP(ORDER BY CAST(VISIT_PAGE_NBR as INT))
AS No_Of_Views
FROM db_name.schema_name.tbl_name
WHERE FLG_COLUMN = '0'
AND SOURCE_CD NOT IN ('1','2','3','4')
AND DATE_CR = '2022-01-01'
GROUP BY ID;
I want the VIEW_NM column values to be displayed either in ASC or DESC order. But when I do a DISTINCT VIEW_NM, I'm getting - It is not a valid ORDER BY expression. Need help in fixing this.
Also, I don't want the values of VIEW_NM column to be duplicated. Pls suggest how this can be done..
Using cte to filter out multiple VIEW_NM per ID(choosing the one with lowest VIST_PAGE_NBR):
WITH cte AS (
SELECT ID, VIEW_NM, VISIT_PAGE_NBR::INT AS VISIT_PAGE_NBR
FROM db_name.schema_name.tbl_name
WHERE FLG_COLUMN = '0'
AND SOURCE_CD NOT IN ('1','2','3','4')
AND DATE_CR = '2022-01-01'
QUALIFY ROW_NUMBER() OVER(PARTITION BY ID,VIEW_NM ORDER BY VISIT_PAGE_NBR) = 1
)
SELECT ID,
LISTAGG(VIEW_VM, ',') WITHIN GROUP(ORDER BY VISIT_PAGE_NBR) AS No_Of_Views
FROM cte
GROUP BY ID;

DISTINCT with PagedResults

I am sure this will be answered somewhere...
Aim: Get DISTINCT DOCURL and additional columns
Tried:
1. Changing SELECT * FROM to SELECT DISTINCT DOCURL FROM which only yields the DOCURL column
2. Adding DISTINCT into the second select (as per example) but again I get all columns and rows.
Notes: Code is normally built dynamically so I've taken the print...
SELECT *
FROM
(
Select DISTINCT
isnull(d.DOCURL,'-') As DOCURL,
isnull(d.ID,'-') As ID,
isnull(d.UPRN,'-') As UPRN,
isnull(d.VFMDISCIPLINE,'-') As VFMDISCIPLINE,
isnull(d.VFMDISCIPLINEELEMENT,'-') As VFMDISCIPLINEELEMENT ,
isnull(d.SurveyDate,' ') As SurveyDate,
isnull(d.WorkOrder,'-') As WorkOrder,
ROW_NUMBER() OVER (ORDER BY DOCURL) AS ResultSetRowNumber
From TblData As D
WHERE 1 = 1
AND d.UPRN = '123XYZ'
AND (d.VFMDISCIPLINE = '1' OR d.VFMDISCIPLINE = '2' )
) As PagedResults
WHERE ResultSetRowNumber > 0 And ResultSetRowNumber <= 20
Assuming DOCURL is a unique column, the issue with the DISTINCT statement is that a new row number will be generated for each row in the sub query, therefore all rows will be considered different. You should apply distinct first and then get the row numbers.
Edit: I removed DISTINCT since your result set do not satisfy the criteria. Instead, I've added a partition inside the sub query, this way row numbers will start from 1 for each unique DOCURL and they're ordered by ID since I just assumed that's what you mean by first. Outer query reassigns row_numbers based on unique results from the sub query.
Select * From (
SELECT *, ROW_NUMBER() OVER (ORDER BY DOCURL) AS ResultSetRowNumber
FROM
(
Select
isnull(d.DOCURL,'-') As DOCURL,
isnull(d.ID,'-') As ID,
isnull(d.UPRN,'-') As UPRN,
isnull(d.VFMDISCIPLINE,'-') As VFMDISCIPLINE,
isnull(d.VFMDISCIPLINEELEMENT,'-') As VFMDISCIPLINEELEMENT ,
isnull(d.SurveyDate,' ') As SurveyDate,
isnull(d.WorkOrder,'-') As WorkOrder,
ROW_NUMBER() OVER (PARTITION BY d.DOCURL ORDER BY d.ID) As PART
From TblData As D
WHERE 1 = 1
AND d.UPRN = '123XYZ'
AND (d.VFMDISCIPLINE = '1' OR d.VFMDISCIPLINE = '2' )
) As t Where PART = 1
) As PagedResults
WHERE ResultSetRowNumber > 0 And ResultSetRowNumber <= 20

SQL SERVER QUERY to select max value record per item

This is the sample table
What I need to achieve is to get or display only the record of tenant with the highest month value. If ever month is equal, I need to base on the latest date value. Here is the sample desired output
With this, I started by this code using max function and incorporated temp table, but unable to get the desired result.
select tenant, name, date, month
into #sample
from tenant
select *
from #sample
where months = (select max(months)from #sample)
and output to something like this. As I believe, the code is getting the max value in the whole list not considering per tenant filtering.
Any help will be greatly appreciated :)
This can be done with the row_number window function:
select tenant, name, date, months
from (select t.*,
row_number() over (partition by t.tenant, t.name order by t.months desc, t.date desc) as rn
from TableName t) x
where rn = 1
You can use a row_number function.
Query
;with cte as
(
select rn = row_number() over
(
partition by tenant
order by months desc,[date] desc
),*
from table_name
)
select tenant,name,[date],months from cte
where rn = 1;

Total Row Count in sql query---sql server 2008

My query is as follows
BEGIN
WITH MyCTE
AS (
SELECT T.MusicAlbumTitle
,D.musicTitle
,D.mVideoID
,D.musicFileName
,T.ReleaseDate AS ReleasedDate
,D.MusicLength
,D.musicSinger
,D.MusicVideoID
,D.ExternalLink
,D.CoverImg
,ROW_NUMBER() OVER (
PARTITION BY D.MusicVideoID ORDER BY D.mVideoID
) AS row_num
FROM dbo.Music_Video T
JOIN dbo.Music_Video_Details D ON T.MusicVideoID = D.MusicVideoID
WHERE T.PortalID = #PortalID
AND T.CultureCode = #CultureCode
AND T.ComingSoon <> 1
GROUP BY T.MusicAlbumTitle
,D.musicTitle
,D.mVideoID
,T.ReleaseDate
,D.musicFileName
,D.MusicLength
,D.musicSinger
,D.MusicVideoID
,D.ExternalLink
,D.CoverImg
)
SELECT a.mVideoID
,a.MusicVideoID
,a.musicFileName
,a.MusicAlbumTitle
,a.ReleasedDate
,a.row_num
,a.CoverImg
,a.ExternalLink
,a.musicTitle
,a.MusicLength
FROM MyCTE a
WHERE row_num = 1
ORDER BY MusicVideoID DESC
END
I need to achieve total row count from last select statement.
which mean total row count that is being selected.
or any idea that might be use in this condition
How can i do this ..
Please add COUNT(*) OVER() in your select, which returns total rows selected as a new column.
Ex:
SELECT
*,
COUNT(*) OVER() AS [Total_Rows]
FROM YourTable
Just to be clear, you need to add the count to the CTE, not the outer query. The outer select is returning only one row, so the count would always be one.
The CTE should start:
WITH MyCTE
AS (
SELECT T.MusicAlbumTitle
,D.musicTitle
,D.mVideoID
,D.musicFileName
,T.ReleaseDate AS ReleasedDate
,D.MusicLength
,D.musicSinger
,D.MusicVideoID
,D.ExternalLink
,D.CoverImg
,ROW_NUMBER() OVER (
PARTITION BY D.MusicVideoID ORDER BY D.mVideoID
) AS row_num,
COUNT(*) over () as total_count