USE DNWorld
GO
SELECT TOP (100) WITH TIES PvPExp
FROM PvPRanking
ORDER BY PVPExp DESC
UPDATE PVPRanking
SET PVPLevel = 26
WHERE TOP(1) = 1
ERROR:
Msg 156, Level 15, State 1, Server NS544979, Procedure , Line 0
Incorrect syntax near the keyword 'TOP'.
[42000] [Microsoft][SQL Server Native Client 11.0][SQL Server]Incorrect syntax near the keyword 'TOP'. (156)
I have successfully selected and ordered the PvPExp in the query.
I want to set PVPLEVEL = 26 for the #1 Top result. That isn't working.
Then from that I want to set The #2-#5 Top result a certain value.
So on and so forth. Please help
With RANK() window function:
WITH cte AS (
SELECT *, RANK() OVER (ORDER BY PVPExp DESC) AS rn
FROM PvPRanking
)
UPDATE cte
SET PVPLevel = CASE rn
WHEN 1 THEN 26
ELSE ?
END
WHERE rn <= 5
Replace ? with the value that you want to set to #2-#5 Top rows.
If you want to set different values for them also:
.............................
SET PVPLevel = CASE rn
WHEN 1 THEN 26
WHEN 2 THEN ?
WHEN 3 THEN ?
WHEN 4 THEN ?
WHEN 5 THEN ?
END
.............................
You can use row_number() with a CTE. ie:
with rankings (PvpExp, rowNo) as
(
SELECT PvPExp, row_number() over (order by PvpExp desc)
FROM PvPRanking
)
UPDATE PVPRanking
SET PVPLevel = case
when r.rowNo = 1 then 26
when r.rowNo > 1 and r.rowNo < 6 then xx
-- other settings
end
from PVPRanking pr
inner join rankings r on pr.PVPExp = r.PVPExp;
What you need might be Rank(), DenseRank() ... instead of row_number() based on your real needs.
Related
I want to
Filter a data set
Take distinct of a column
take out top 10 rows of that data set with the distinct column
The code I am using is
SELECT TOP (10) *
FROM (
SELECT DISTINCT(business_id) FROM businessdata
WHERE businessdata.city = 'Phoenix'
)
;
and the error I am getting is
Msg 102, Level 15, State 1, Line 7
Incorrect syntax near ';'.
Where am I going wrong?
You have to give a name to the subquery:
SELECT TOP (10) *
FROM (
SELECT DISTINCT(business_id) FROM businessdata
WHERE businessdata.city = 'Phoenix'
) AS my_subquery
ORDER BY businessdata
;
make sure you also an ORDER BY to correctly set the order and thus make TOP meaningful
This question already has answers here:
How do I do top 1 in Oracle? [duplicate]
(9 answers)
Closed 4 years ago.
How to limit the output to only get the first row in ORACLE.
I tried FETCH first 1 rows only; But it is giving sql not ended properly error message
Current OUTPUT
70 19-APR-18 Base Line Date
71 20-JUN-19 Target Date
73 23-JUN-18
QUERY
SELECT EXEC_TRACKER_SESSION_SEQ,
(CASE WHEN tsm.SESSION_SEQ IS NULL THEN tsm.TAGETDATE ELSE s.SESSION_DATE END) as SESSION_DATE
,tsm.NOTES
FROM TRACKER_SESSION_MAP tsm
LEFT JOIN session s ON tsm.session_seq = s.session_seq
WHERE tsm.TRACKER_SEQ =244
order by TRACKER_SESSION_SEQ ASC
Required Output
70 19-APR-18 Base Line Date
Use rownum=1 as :
select * from
(
SELECT EXEC_TRACKER_SESSION_SEQ,
(CASE WHEN tsm.SESSION_SEQ IS NULL THEN tsm.TAGETDATE ELSE s.SESSION_DATE END) as SESSION_DATE
,tsm.NOTES
FROM TRACKER_SESSION_MAP tsm
LEFT JOIN session s ON tsm.session_seq = s.session_seq
WHERE tsm.TRACKER_SEQ =244
order by TRACKER_SESSION_SEQ ASC
)
where rownum=1;
Alternatively you may use row_number() function as :
select * from
(
SELECT EXEC_TRACKER_SESSION_SEQ,
(CASE WHEN tsm.SESSION_SEQ IS NULL THEN tsm.TAGETDATE ELSE s.SESSION_DATE END) as SESSION_DATE
,tsm.NOTES, row_number() over (order by day) as rn
FROM TRACKER_SESSION_MAP tsm
LEFT JOIN session s ON tsm.session_seq = s.session_seq
WHERE tsm.TRACKER_SEQ =244
order by TRACKER_SESSION_SEQ ASC
)
where rn=1;
fetch..rows statement works provided that you use Oracle 12c.
You need
WHERE ROWNUM=1
Oracle doesn't have a top X function, but it always knows what the rownumber, so take advantage.
When I execute the following query:
SELECT
MH.MemberKey,
ROW_NUMBER() OVER(PARTITION BY MH.MemberKey ORDER BY MH.MemberKey ASC) AS "NewRow",
MH.FirstName,
MH.LastName,
MH.BirthDate,
MH.AddressLine1,
MH.AddressLine2,
MH.AddressLine3,
MH.City AS MemberCity,
MH.StateCode AS MemberState,
MH.ZipCode AS MemberZip
FROM MembershipHistory MH
WHERE NewRow = 1;
I get the following error:
Msg 207, Level 16, State 1, Line 36
Invalid column name 'NewRow'.
I tried keeping AS, removing AS, removing ""....nothing seems to work. It just wont recognize the column.
The evaluation of the row_number function in the SELECT is done after the WHERE clause has been applied so the alias is not recognized, you can use a subquery to get the result:
select
MH.MemberKey,
NewRow,
MH.FirstName,
MH.LastName,
MH.BirthDate,
MH.AddressLine1,
MH.AddressLine2,
MH.AddressLine3,
MH.City AS MemberCity,
MH.StateCode AS MemberState,
MH.ZipCode AS MemberZip
from
(
SELECT
MH.MemberKey,
ROW_NUMBER() OVER(PARTITION BY MH.MemberKey ORDER BY MH.MemberKey ASC) AS NewRow,
MH.FirstName,
MH.LastName,
MH.BirthDate,
MH.AddressLine1,
MH.AddressLine2,
MH.AddressLine3,
MH.City AS MemberCity,
MH.StateCode AS MemberState,
MH.ZipCode AS MemberZip
FROM MembershipHistory MH
) MH
WHERE NewRow = 1;
In SQL Server the Logical Processinf Order of the SELECT Statement is (from MSDN Docs):
FROM
ON
JOIN
WHERE
GROUP BY
WITH CUBE or WITH ROLLUP
HAVING
SELECT
DISTINCT
ORDER BY
TOP
Another approach is to use a CTE:
;WITH x AS (SELECT MH.whatever, ROW_NUMBER() ... AS NewRow FROM dbo.table)
SELECT * FROM x WHERE NewRow = 1;
What do I have to do to use name Rowss in the WHERE clause ?
SELECT TOP 10
ROW_NUMBER() OVER(ORDER BY dp.IdPytanie) AS Rowss,
dp.IdPytanie
,dp.SpecjalnePytanie
FROM dodajtemat_pytanie dp
WHERE
(#RowBegining = 0 OR convert(int,Rowss) >= #RowBegining)
AND (#RowEnd = 0 OR Rowss <= #RowEnd)
Error
This work ->
#RowEnd = 0 OR ROW_NUMBER() OVER(ORDER BY dp.IdPytanie) <= #RowEnd
Use a subquery or a CTE like this:
WITH CTE
AS
(
SELECT
ROW_NUMBER() OVER(ORDER BY dp.IdPytanie) AS Rowss,
dp.IdPytanie,
dp.SpecjalnePytanie
FROM dodajtemat_pytanie dp
)
SELECT *
FROM CTE
WHERE (#RowBegining = 0 OR Rowss >= #RowBegining)
AND (#RowEnd = 0 OR Rowss <= #RowEnd);
The WHERE clause is logically evaluated before the SELECT statement, so that it doesn't recognize that newly created alias Rowss.
Fore more information about the logical query processing steps in SQL Server, see:
Logical Query Processing Poster by Itzik Ben
I need to use ROW_NUMBER() in the following Query to return rows 5 to 10 of the result. Can anyone please show me what I need to do? I've been trying to no avail. If anyone can help I'd really appreciate it.
SELECT *
FROM villa_data
INNER JOIN villa_prices
ON villa_prices.starRating = villa_data.starRating
WHERE villa_data.capacity >= 3
AND villa_data.bedrooms >= 1
AND villa_prices.period = 'lowSeason'
ORDER BY villa_prices.price,
villa_data.bedrooms,
villa_data.capacity
You need to stick it in a table expression to filter on ROW_NUMBER. You won't be able to use * as it will complain about the column name starRating appearing more than once so will need to list out the required columns explicitly. This is better practice anyway.
WITH CTE AS
(
SELECT /*TODO: List column names*/
ROW_NUMBER()
OVER (ORDER BY villa_prices.price,
villa_data.bedrooms,
villa_data.capacity) AS RN
FROM villa_data
INNER JOIN villa_prices
ON villa_prices.starRating = villa_data.starRating
WHERE villa_data.capacity >= 3
AND villa_data.bedrooms >= 1
AND villa_prices.period = 'lowSeason'
)
SELECT /*TODO: List column names*/
FROM CTE
WHERE RN BETWEEN 5 AND 10
ORDER BY RN
You can use a with clause. Please try the following
WITH t AS
(
SELECT villa_data.starRating,
villa_data.capacity,
villa_data.bedrooms,
villa_prices.period,
villa_prices.price,
ROW_NUMBER() OVER (ORDER BY villa_prices.price,
villa_data.bedrooms,
villa_data.capacity ) AS 'RowNumber'
FROM villa_data
INNER JOIN villa_prices
ON villa_prices.starRating = villa_data.starRating
WHERE villa_data.capacity >= 3
AND villa_data.bedrooms >= 1
AND villa_prices.period = 'lowSeason'
)
SELECT *
FROM t
WHERE RowNumber BETWEEN 5 AND 10;