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

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

Related

Select every second record then determine earliest date

I have table that looks like the following
I have to select every second record per PatientID that would give the following result (my last query returns this result)
I then have to select the record with the oldest date which would be the following (this is the end result I want)
What I have done so far: I have a CTE that gets all the data I need
WITH cte
AS
(
SELECT visit.PatientTreatmentVisitID, mat.PatientMatchID,pat.PatientID,visit.RegimenDate AS VisitDate,
ROW_NUMBER() OVER(PARTITION BY mat.PatientMatchID, pat.PatientID ORDER BY visit.VisitDate ASC) AS RowNumber
FROM tblPatient pat INNER JOIN tblPatientMatch mat ON mat.PatientID = pat.PatientID
LEFT JOIN tblPatientTreatmentVisit visit ON visit.PatientID = pat.PatientID
)
I then write a query against the CTE but so far I can only return the second row for each patientID
SELECT *
FROM
(
SELECT PatientTreatmentVisitID,PatientMatchID,PatientID, VisitDate, RowNumber FROM cte
) as X
WHERE RowNumber = 2
How do I return the record with the oldest date only? Is there perhaps a MIN() function that I could be including somewhere?
If I follow you correctly, you can just order your existing resultset and retain the top row only.
In standard SQL, you would write this using a FETCH clause:
SELECT *
FROM (
SELECT
visit.PatientTreatmentVisitID,
mat.PatientMatchID,
pat.PatientID,
visit.RegimenDate AS VisitDate,
ROW_NUMBER() OVER(PARTITION BY mat.PatientMatchID, pat.PatientID ORDER BY visit.VisitDate ASC) AS rn
FROM tblPatient pat
INNER JOIN tblPatientMatch mat ON mat.PatientID = pat.PatientID
LEFT JOIN tblPatientTreatmentVisit visit ON visit.PatientID = pat.PatientID
) t
WHERE rn = 2
ORDER BY VisitDate
OFFSET 0 ROWS FETCH FIRST 1 ROW ONLY
This syntax is supported in Postgres, Oracle, SQL Server (and possibly other databases).
If you need to get oldest date from all selected dates (every second row for each patient ID) then you can try window function Min:
SELECT * FROM
(
SELECT *, MIN(VisitDate) OVER (Order By VisitDate) MinDate
FROM
(
SELECT PatientTreatmentVisitID,PatientMatchID,PatientID, VisitDate,
RowNumber FROM cte
) as X
WHERE RowNumber = 2
) Y
WHERE VisitDate=MinDate
Or you can use SELECT TOP statement. The SELECT TOP clause allows you to limit the number of rows returned in a query result set:
SELECT TOP 1 PatientTreatmentVisitID,PatientMatchID,PatientID, VisitDate FROM
(
SELECT *
FROM
(
SELECT PatientTreatmentVisitID,PatientMatchID,PatientID, VisitDate,
RowNumber FROM cte
) as X
WHERE RowNumber = 2
) Y
ORDER BY VisitDate
For simplicity add order desc on date column and use TOP to get the first row only
SELECT TOP 1 *
FROM
(
SELECT PatientTreatmentVisitID,PatientMatchID,PatientID, VisitDate, RowNumber FROM cte
) as X
WHERE RowNumber = 2
order by VisitDate desc

Parameters for fetch first rows in query

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;

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

Apply aggregate function on subset of rows

I have a table that I want to calculate the average of one column but only for the last 10 rows.
SELECT AVG(columnName) as avg FROM tableName
I cannot apply top directly since this query only returns one row. I need a way to get the latest 10 rows and do the average on them.
Try this:
SELECT AVG(columnName) FROM
(SELECT TOP 10 columnName FROM tableName ORDER BY ColumnWhichHoldsOrder DESC) A
select avg(columnName)
from (
select columnName,
row_number() over (order by some column desc) as rn
from tableName
) t
where rn <= 10;

Selecting the 2nd row in sql

I want to select the second row only from the table. From the ClientUserName column.
SELECT
ClientUserName, DestHost, count(DestHost) counts
FROM
#ProxyLog_record
WHERE
ClientUserName = (Select top 1 ClientUserName from #ProxyLog_count_2)
GROUP BY
ClientUserName, DestHost
ORDER BY
counts DESC
The (Select top 1 ClientUserName from #ProxyLog_count_2) shows top 1 only but I need to get the 2nd data from that table. How can I do this?
Presumably, you are using SQL Server. The "top 1" is selecting a random row from the table, because you have no order by clause.
If you want the second row inserted into the table, the way to do this is to define an auto-incrementing column in the table. The create table statement should include:
create table #ProxyLog_count_2 (
ProxyLog_Count_2_id int not null identity(1,1),
...
)
You can then get the second row inserted by using the simple where clause:
where ProxyLog_Count_2_id = 2
Easiest way would be to use the ROW_NUMBER() method like so:
WITH c AS (
SELECT
ClientUserName, DestHost, count(DestHost) counts, ROW_NUMBER() OVER(ORDER BY count(DestHost)) AS rowNum
FROM
#ProxyLog_record
GROUP BY
ClientUserName, DestHost
)
SELECT ClientUserName, DestHost, counts
FROM c
WHERE rowNum = 2
(Don't use count(DestHost) counts if it's not required, or use another CTE to save counting twice)
Try:
SELECT
ClientUserName, DestHost, count(DestHost) counts
FROM
#ProxyLog_record
WHERE
ClientUserName = (
;with cte as
(
select ROW_NUMBER() over (order by ClientUserName) as rn, *
from #ProxyLog_count_2
)
select ClientUserName from cte where rn=2
)
GROUP BY
ClientUserName, DestHost
ORDER BY
counts DESC
Based on what you've tried so far...
SELECT top 1
ClientUserName, DestHost, count(DestHost) counts
FROM
#ProxyLog_record
WHERE
ClientUserName <> (Select top 1 ClientUserName from #ProxyLog_count_2)
GROUP BY
ClientUserName, DestHost
ORDER BY
counts DESC
You could use ROW_NUMBER()...
You could use a cursor...
You could put an identifier in the top row to allow you to filter it out (and then subsequently, select the top 1 again and you'd have it).
Otherwise, if there is something identifiable about the 2nd row (does it have the highest something, or the lowest, or the most recent date, etc.),
Wjy not just select top 2 and take the aecomd row from esult set?
SELECT Top 1 a.ClientUserName, a.DestHost, a.counts
FROM
(
SELECT Top 2
ClientUserName, DestHost, count(DestHost) counts
FROM
#ProxyLog_record
WHERE
ClientUserName = (Select top 1 ClientUserName from #ProxyLog_count_2)
GROUP BY
ClientUserName, DestHost
ORDER BY
counts DESC
)
as a
ORDER BY a.Counts ASC