查询按类型分组,考虑具有优先级的分组
Query to group by a type considering a grouping with a priority scale
我需要根据类型并考虑优先级对一些数据进行分组。
以下面的 CTE 为例。
WITH classif AS
(
select 1 as id, 'account' as type, 'high' as priority from dual union all
select 2 as id, 'account' as type, 'none' as priority from dual union all
select 3 as id, 'account' as type, 'medium' as priority from dual union all
select 4 as id, 'security' as type, 'high' as priority from dual union all
select 5 as id, 'security' as type, 'medium' as priority from dual union all
select 6 as id, 'security' as type, 'low' as priority from dual union all
select 7 as id, 'security' as type, 'none' as priority from dual union all
select 8 as id, 'transform' as type, 'none' as priority from dual union all
select 9 as id, 'transform' as type, 'none' as priority from dual union all
select 10 as id, 'transform' as type, 'none' as priority from dual union all
select 11 as id, 'transform' as type, 'none' as priority from dual union all
select 12 as id, 'enrollment' as type, 'medium' as priority from dual union all
select 13 as id, 'enrollment' as type, 'low' as priority from dual union all
select 14 as id, 'enrollment' as type, 'low' as priority from dual union all
select 15 as id, 'enrollment' as type, 'low' as priority from dual;
select 15 as id, 'process' as type, 'low' as priority from dual;
select 15 as id, 'process' as type, 'none' as priority from dual;
select 15 as id, 'process' as type, 'none' as priority from dual;
)
对于这个数据集,我的输出必须是这样的
------------+-------------
type | priority
------------+-------------
account | high
security | high
transform | none
enrollment | medium
process | low
---------------------------
优先级从“高”到“none”
输出的规则必须是这样的
- 当类型具有优先级为“高”的行时,该类型的输出必须为“高”。
- 当类型具有优先级为“中”且没有其他优先级的行时
使用“高”,输出必须为“中”。
- 当类型具有优先级为“低”且没有其他优先级的行时
使用“高”或“中”,输出必须为“低”。
- 当类型具有优先级为“none”且没有任何优先级的行时
其他,输出必须是“none”
我正在尝试执行类似于下面这个查询的操作,但这将 return 所有行而不是根据优先级分组
select
type,
case
when priority = 'high' then 'high'
when priority = 'medium' and priority <> 'high' then 'medium'
when priority = 'medium' and priority <> 'high' then 'medium'
when priority = 'low' and priority <> 'high' or priority <> 'medium' then 'low'
when priority = 'none' and priority <> 'high' or priority <> 'medium' or priority <> 'low' then 'none'
end as priority
from classif
group by type,
case
when priority = 'high' then 'high'
when priority = 'medium' and priority <> 'high' then 'medium'
when priority = 'medium' and priority <> 'high' then 'medium'
when priority = 'low' and priority <> 'high' or priority <> 'medium' then 'low'
when priority = 'none' and priority <> 'high' or priority <> 'medium' or priority <> 'low' then 'none'
end;
你能帮我在查询中解决这个问题吗?
您可以使用 ROW_NUMBER
和 order by a CASE
语句将优先级转换为数值:
SELECT id, type, priority
FROM (
SELECT c.*,
ROW_NUMBER() OVER (
PARTITION BY type
ORDER BY CASE priority
WHEN 'high' THEN 1
WHEN 'medium' THEN 2
WHEN 'low' THEN 3
ELSE 4
END
) AS rn
FROM classif c
)
WHERE rn = 1;
或者,您可以使用 MAX(...) KEEP (DENSE RANK FIRST ...)
并使用 CASE
语句进行类似的排序:
SELECT MAX(id) KEEP (
DENSE_RANK FIRST
ORDER BY CASE priority
WHEN 'high' THEN 1
WHEN 'medium' THEN 2
WHEN 'low' THEN 3
ELSE 4
END
) AS id,
type,
MAX(priority) KEEP (
DENSE_RANK FIRST
ORDER BY CASE priority
WHEN 'high' THEN 1
WHEN 'medium' THEN 2
WHEN 'low' THEN 3
ELSE 4
END
) AS priority
FROM classif
GROUP BY type
或者,您可以使用子查询来存储相对优先级并使用连接:
SELECT MAX(c.id) KEEP (DENSE_RANK LAST ORDER BY p.id) AS id,
type,
MAX(c.priority) KEEP (DENSE_RANK LAST ORDER BY p.id) AS priority
FROM classif c
LEFT OUTER JOIN (
SELECT 'high' AS priority, 3 As id FROM DUAL UNION ALL
SELECT 'medium', 2 FROM DUAL UNION ALL
SELECT 'low', 1 FROM DUAL UNION ALL
SELECT 'none', 0 FROM DUAL
) p
ON c.priority = p.priority
GROUP BY c.type
其中,对于您的示例数据,所有输出:
ID
TYPE
PRIORITY
1
account
high
12
enrollment
medium
15
process
low
4
security
high
8
transform
none
db<>fiddle here
我需要根据类型并考虑优先级对一些数据进行分组。
以下面的 CTE 为例。
WITH classif AS
(
select 1 as id, 'account' as type, 'high' as priority from dual union all
select 2 as id, 'account' as type, 'none' as priority from dual union all
select 3 as id, 'account' as type, 'medium' as priority from dual union all
select 4 as id, 'security' as type, 'high' as priority from dual union all
select 5 as id, 'security' as type, 'medium' as priority from dual union all
select 6 as id, 'security' as type, 'low' as priority from dual union all
select 7 as id, 'security' as type, 'none' as priority from dual union all
select 8 as id, 'transform' as type, 'none' as priority from dual union all
select 9 as id, 'transform' as type, 'none' as priority from dual union all
select 10 as id, 'transform' as type, 'none' as priority from dual union all
select 11 as id, 'transform' as type, 'none' as priority from dual union all
select 12 as id, 'enrollment' as type, 'medium' as priority from dual union all
select 13 as id, 'enrollment' as type, 'low' as priority from dual union all
select 14 as id, 'enrollment' as type, 'low' as priority from dual union all
select 15 as id, 'enrollment' as type, 'low' as priority from dual;
select 15 as id, 'process' as type, 'low' as priority from dual;
select 15 as id, 'process' as type, 'none' as priority from dual;
select 15 as id, 'process' as type, 'none' as priority from dual;
)
对于这个数据集,我的输出必须是这样的
------------+-------------
type | priority
------------+-------------
account | high
security | high
transform | none
enrollment | medium
process | low
---------------------------
优先级从“高”到“none”
输出的规则必须是这样的
- 当类型具有优先级为“高”的行时,该类型的输出必须为“高”。
- 当类型具有优先级为“中”且没有其他优先级的行时 使用“高”,输出必须为“中”。
- 当类型具有优先级为“低”且没有其他优先级的行时 使用“高”或“中”,输出必须为“低”。
- 当类型具有优先级为“none”且没有任何优先级的行时 其他,输出必须是“none”
我正在尝试执行类似于下面这个查询的操作,但这将 return 所有行而不是根据优先级分组
select
type,
case
when priority = 'high' then 'high'
when priority = 'medium' and priority <> 'high' then 'medium'
when priority = 'medium' and priority <> 'high' then 'medium'
when priority = 'low' and priority <> 'high' or priority <> 'medium' then 'low'
when priority = 'none' and priority <> 'high' or priority <> 'medium' or priority <> 'low' then 'none'
end as priority
from classif
group by type,
case
when priority = 'high' then 'high'
when priority = 'medium' and priority <> 'high' then 'medium'
when priority = 'medium' and priority <> 'high' then 'medium'
when priority = 'low' and priority <> 'high' or priority <> 'medium' then 'low'
when priority = 'none' and priority <> 'high' or priority <> 'medium' or priority <> 'low' then 'none'
end;
你能帮我在查询中解决这个问题吗?
您可以使用 ROW_NUMBER
和 order by a CASE
语句将优先级转换为数值:
SELECT id, type, priority
FROM (
SELECT c.*,
ROW_NUMBER() OVER (
PARTITION BY type
ORDER BY CASE priority
WHEN 'high' THEN 1
WHEN 'medium' THEN 2
WHEN 'low' THEN 3
ELSE 4
END
) AS rn
FROM classif c
)
WHERE rn = 1;
或者,您可以使用 MAX(...) KEEP (DENSE RANK FIRST ...)
并使用 CASE
语句进行类似的排序:
SELECT MAX(id) KEEP (
DENSE_RANK FIRST
ORDER BY CASE priority
WHEN 'high' THEN 1
WHEN 'medium' THEN 2
WHEN 'low' THEN 3
ELSE 4
END
) AS id,
type,
MAX(priority) KEEP (
DENSE_RANK FIRST
ORDER BY CASE priority
WHEN 'high' THEN 1
WHEN 'medium' THEN 2
WHEN 'low' THEN 3
ELSE 4
END
) AS priority
FROM classif
GROUP BY type
或者,您可以使用子查询来存储相对优先级并使用连接:
SELECT MAX(c.id) KEEP (DENSE_RANK LAST ORDER BY p.id) AS id,
type,
MAX(c.priority) KEEP (DENSE_RANK LAST ORDER BY p.id) AS priority
FROM classif c
LEFT OUTER JOIN (
SELECT 'high' AS priority, 3 As id FROM DUAL UNION ALL
SELECT 'medium', 2 FROM DUAL UNION ALL
SELECT 'low', 1 FROM DUAL UNION ALL
SELECT 'none', 0 FROM DUAL
) p
ON c.priority = p.priority
GROUP BY c.type
其中,对于您的示例数据,所有输出:
ID TYPE PRIORITY 1 account high 12 enrollment medium 15 process low 4 security high 8 transform none
db<>fiddle here