Is it possible to rank item by partition without use CTE method
Expected Table
| item | value | ID |
|---|---|---|
| A | 10 | 1 |
| A | 20 | 1 |
| B | 30 | 2 |
| B | 40 | 2 |
| C | 50 | 3 |
| C | 60 | 3 |
| A | 70 | 4 |
| A | 80 | 4 |
By giving id to the partition to allow agitated function to work the way I want.
| item | MIN | MAX | ID |
|---|---|---|---|
| A | 10 | 20 | 1 |
| B | 30 | 40 | 2 |
| C | 50 | 60 | 3 |
| A | 70 | 80 | 4 |
SQL Version: Microsoft SQL Sever 2017
CodePudding user response:
Assuming that the value column provides the intended ordering of the records which we see in your question above, we can try using the difference in row numbers method here. Your problem is a type of gaps and islands problem.
WITH cte AS (
SELECT *, ROW_NUMBER() OVER (ORDER BY value) rn1,
ROW_NUMBER() OVER (PARTITION BY item ORDER BY value) rn2
FROM yourTable
)
SELECT item, MIN(value) AS [MIN], MAX(value) AS [MAX], MIN(ID) AS ID
FROM cte
GROUP BY item, rn1 - rn2
ORDER BY MIN(value);
Demo
If you don't want to use a CTE here, for whatever reason, you may simply inline the SQL code in the CTE into the bottom query, as a subquery:
SELECT item, MIN(value) AS [MIN], MAX(value) AS [MAX], MIN(ID) AS ID
FROM
(
SELECT *, ROW_NUMBER() OVER (ORDER BY value) rn1,
ROW_NUMBER() OVER (PARTITION BY item ORDER BY value) rn2
FROM yourTable
) t
GROUP BY item, rn1 - rn2
ORDER BY MIN(value);
CodePudding user response:
You can generate group IDs by analyzing the previous row item value that could be obtained with the LAG function and finally use GROUP BY to get the minimum and maximum value in item groups.
SELECT
item,
MIN(value) AS "min",
MAX(value) AS "max",
group_id 1 AS id
FROM (
SELECT
*,
SUM(CASE WHEN item = prev_item THEN 0 ELSE 1 END) OVER (ORDER BY value) AS group_id
FROM (
SELECT
*,
LAG(item, 1, item) OVER (ORDER BY value) AS prev_item
FROM t
) items
) groups
GROUP BY item, group_id
Query produces output
| item | min | max | id |
|---|---|---|---|
| A | 10 | 20 | 1 |
| B | 30 | 40 | 2 |
| C | 50 | 60 | 3 |
| A | 70 | 80 | 4 |
You can check a working demo here

