I need to do order by UserId in this inner select (so before this last WHERE clause is considered) but since I get error
The ORDER BY clause is invalid in views, inline functions...
I cant do it that way. Is there some other way I can order by UserId and DENSE_RANK() by JobId as is now?
Most of UserId values are NULL and when dense_ranked by JobId I need to sort those JobIds so that first are ones where UserId != NULL
SELECT *, #RecordCount as RecordCount
FROM
(
SELECT JobId, UserId, DENSE_RANK() OVER(ORDER BY JobId) AS Rnk
FROM #ListOfJobs
) t
WHERE Rnk between (#pn - 1) * #ps + 1 and #pn * #ps
What's about using CTE for obtaining the dense_rank and then sorting by UserId in the derived result set:
;WITH cte AS (
SELECT JobId, UserId, DENSE_RANK() OVER(ORDER BY JobId) AS Rnk
FROM #ListOfJobs
WHERE Rnk between (#pn - 1) * #ps + 1 and #pn * #ps
)
SELECT * FROM cte
ORDER BY UserId DESC, Rnk
How about using order by for both JobID and UserId.
SELECT TOP 100 PERCENT *, #RecordCount as RecordCount
FROM
(
SELECT JobId, UserId, DENSE_RANK() OVER(ORDER BY JobId) AS Rnk
FROM #ListOfJobs ORDER BY UserId
) t
WHERE Rnk between (#pn - 1) * #ps + 1 and #pn * #ps
If you simply want to first list all the entries with where UserId is specified and then those where it is not, you could just modify your DENSE_RANK expression like this:
DENSE_RANK() OVER (ORDER BY CASE WHEN UserId IS NULL THEN 1 ELSE 0 END, JobId)
That effectively sorts by two columns, of which the first one is a flag that indicates whether UserId is null or not and the second one is JobId. Rows where the flag is 0 will be assigned lower Rnk values than rows where the flag is 1.
Related
I have to select CompanyId column only from the following SQL;
select CompanyId,
row_number() over (partition by [GradeName] order by [TankNumber] ) rn
from [Data_DB].[dbo].[Company] where CompanyCode='ASAAA'
In the SQL, I try to figure out duplicate records, and from another table i want to delete some records based on the CompanyId from above query.
that is;
delete from [[dbo].ObservationData
where CompanyId in (select CompanyId,
row_number() over (partition by [GradeName] order by [TankNumber] ) rn
from [Data_DB].[dbo].[Company] where CompanyCode='ASAAA')
How can I modify above query?
Assuming you don't care which duplicate gets retained or deleted, you may try using a deletable CTE here:
WITH cte AS (
SELECT *,
ROW_NUMBER() OVER (PARTITION BY [GradeName] ORDER BY [TankNumber]) rn
FROM [Data_DB].[dbo].[Company]
WHERE CompanyCode = 'ASAAA'
)
DELETE
FROM cte
WHERE rn > 1;
This answer arbitrarily retains the "first" duplicate, with first being defined as the record with the earliest row number.
delete from [[dbo].ObservationData
where CompanyId in (select CompanyId from (select CompanyId,
row_number() over (partition by [GradeName] order by [TankNumber] ) rn
from [Datat_DB].[dbo].[Company] where CompanyCode='ASAAA') a where rn > 1 ;
Here the SQL query
;WITH rankedresults AS
(
SELECT
userid,
rowid
FROM
(SELECT
userid,
ROW_NUMBER() OVER (ORDER BY referredplayercount DESC) AS RowId
FROM
tblusersprofile) dt
WHERE
rowid BETWEEN 1 AND 50
)
SELECT
tblusersprofile.userid,
referredplayercount,
username,
avatarimagelink,
authoritylevel,
rowid
FROM
tblusersprofile
LEFT JOIN
rankedresults ON tblusersprofile.userid = rankedresults.userid
WHERE
tblusersprofile.userid IN (SELECT rankedresults.userid
FROM rankedresults)
AND referredplayercount > 0
ORDER BY
rowid ASC
Here the returned results which is not expected to have null row number
I wonder that is rankedresults re-generated with this query again?
SELECT rankedresults.userid
FROM rankedresults
Userid is 1137 is only in the tbluserprofile table, and not in the rankedresults CTE.
Because it's a LEFT JOIN, since there's no match, the rowid in the result shows as NULL.
The row_number() function itself can't generate NULL's.
But to make sure that the ROW_NUMBER in the CTE always returns the exact same order, add the userid in the ORDER BY
ROW_NUMBER() OVER (ORDER BY referredplayercount DESC, userid) AS RowId
But perhaps you could avoid using that CTE twice?
;WITH rankedresults AS
(
SELECT
userid,
RowId
FROM
(
SELECT
userid,
ROW_NUMBER() OVER (ORDER BY referredplayercount DESC, userid ASC) AS RowId
FROM tblusersprofile
WHERE referredplayercount > 0
) dt
WHERE RowId BETWEEN 1 AND 50
)
SELECT
usrprof.userid,
usrprof.referredplayercount,
usrprof.username,
usrprof.avatarimagelink,
usrprof.authoritylevel,
rr.rowid
FROM
tblusersprofile usrprof
JOIN
rankedresults rr ON rr.userid = usrprof.userid
ORDER BY
rr.RowId ASC
And if you can use OFFSET & FETCH, and you don't really need that RowId in the select?
Then you might not even need a CTE with a row_number to page the results.
declare #offsetrows int = 0;
declare #nextrows int = 50;
SELECT
userid,
referredplayercount,
username,
avatarimagelink,
authoritylevel
FROM tblusersprofile
WHERE referredplayercount > 0
ORDER BY referredplayercount DESC, userid ASC
OFFSET #offsetrows ROWS FETCH NEXT #nextrows ROWS ONLY;
Simplified tests on db<>fiddle here
This question is best explained with an image and the script I have currently... How can I extract a FULL one row per assignment, with the lowest rank, and if there are 2 rows with a denserank as 1, then choose either of them?...
select *
,Dense_RANK() over (partition by [Assignment] order by [Text] desc) as
[DenseRank]
from [dbo].[CLEANSED_T3B_Step1_Res_Withdups____CP]
select * from
(
select *
,Dense_RANK() over (partition by [Assignment] order by [Text] desc, NewID()
) as [DenseRank] from [dbo].[CLEANSED_T3B_Step1_Res_Withdups____CP]
) as A
where A.[DenseRank] = 1
Second script is working perfectly!
SELECT * INTO
[dbo].[CLEANSED_T3B_Step1_COMPLETED]
from
(
select *
,Dense_RANK() over (partition by [Assignment] order by
left([Text],1) desc , [Diff_Doc_Clearing_Date] desc , [Amount] asc
as [DenseRank]
from [dbo].[CLEANSED_T3B_Step1_Res_Withdups____CP]
)
as A
where A.[DenseRank] = 1
No longer need just a random first Tied '1st place', now need to get the one with the highest day diff and then also the highest amount after. SO have adapted everything in this version 3.
It seems you don't want to use DENSE_RANK but ROW_NUMBER.
with cte as(
select t.*, rn = row_number() over(partition by assignment order by [text] desc)
from tablename t
)
select * from cte
where rn = 1
Order by 'newid()' as the 'tie-breaker'
Order by [Text],Newid()
-- This Result Is Right and work correctly:
SELECT AutoId, Name,[Group],[Priority], SUMCalculatedPercent
FROM
(SELECT DISTINCT *,
ROW_NUMBER() OVER
(
PARTITION BY [Group] ORDER BY SUMCalculatedPercent DESC,[Priority]
)
AS ranker
FROM #GroupMasterNameChoose
)Z
WHERE ranker = 1
ORDER BY Z.SUMCalculatedPercent DESC,Z.[Priority]
-- This Result Is Wrong :
SELECT AutoId, Name,[Group],[Priority], SUMCalculatedPercent
INTO #GroupOwner
FROM
(SELECT DISTINCT *,
ROW_NUMBER() OVER
(
PARTITION BY [Group] ORDER BY SUMCalculatedPercent DESC,[Priority]
)
AS ranker
FROM #GroupMasterNameChoose
)Z
WHERE ranker = 1
ORDER BY Z.SUMCalculatedPercent DESC,Z.[Priority]
--
Problem : I Need Store My Right Result To Temp Table
Remove ORDER BY Z.SUMCalculatedPercent DESC,Z.[Priority]
I need a SQL query that returns the top 2 Plans by PlanDate per ClientID. This is all on one table where PlanID is the PrimaryID, ClientID is a foreignID.
This is what I have so far -->
SELECT *
FROM [dbo].[tblPlan]
WHERE [PlanID] IN (SELECT TOP (2) PlanID FROM [dbo].[tblPlan] ORDER BY [PlanDate] DESC)
This, obviously, only returns 2 records where I actually need up to 2 records per ClientID.
This can be done using ROW_NUMBER:
SELECT PlanId, ClientId, PlanDate FROM (
SELECT ROW_NUMBER() OVER (PARTITION BY ClientId ORDER BY PlanDate DESC) rn, *
FROM [dbo].[tblPlan]
) AS T1
WHERE rn <=2
Add any other columns you need to the select to get those too.
Edit, Dec 2011. Corrected CROSS APPLY solution
Try both to see what is best
SELECT *
FROM
( -- distinct ClientID values
SELECT DISTINCT ClientID
FROM [dbo].[tblPlan]
) P1
CROSS APPLY
( -- top 2 per ClientID
SELECT TOP (2) P2.PlanID
FROM [dbo].[tblPlan] P2
WHERE P1.ClientID = P2.ClientID
ORDER BY P2.[PlanDate] DESC
) foo
Or
;WITH cTE AS (
SELECT
*,
ROW_NUMBER () OVER (PARTITION BY clientid ORDER BY [PlanDate] DESC) AS Ranking
FROM
[dbo].[tblPlan]
)
SELECT * FROM cTE WHERE Ranking <= 2