删除条件重复值

时间:2014-11-06 12:37:56

标签: sql oracle

我在查询中使用了16个表,并尝试通过应用以下新更改来优化查询。因此,由于性能问题,我们无法使用group by或union子句,因为无法在现有查询中应用。

我正在按rank / count / rownumber寻找分区,如果可能的话,意味着行级解决方案。

select * FROM (
SELECT 'HA' as CODE,0 AS SR FROM DUAL UNION ALL
SELECT 'HA' as CODE,0 AS SR FROM DUAL UNION ALL
SELECT 'OF' as CODE,0 AS SR FROM DUAL UNION ALL
SELECT 'AC' as CODE,1 AS SR FROM DUAL UNION ALL
SELECT 'OF' as CODE,0 AS SR FROM DUAL UNION ALL
SELECT 'OF' as CODE,1 AS SR FROM DUAL UNION ALL
SELECT 'OF' as CODE,1 AS SR FROM DUAL UNION ALL
SELECT 'XY' as CODE,1 AS SR FROM DUAL UNION ALL
SELECT 'XY' as CODE,1 AS SR FROM DUAL UNION ALL
SELECT 'HA' as CODE,1 AS SR FROM DUAL UNION ALL
SELECT 'OF' as CODE,1 AS SR FROM DUAL )
ORDER BY SR

使用上面的示例数据查询我想:

  1. 将所有行保留在SR = 0
  2. 删除SR = 1行,其中CODE值存在于(SR = 0)
  3. 例如,包括SR = 1的“AC”行,因为没有SR = 0的“AC”行;并且删除SR = 1的“HA”行,因为存在SR = 0的“HA”行。

    此数据的必需输出:

    HA   0
    OF   0
    HA   0
    OF   0
    XY   1
    XY   1
    AC   1
    

2 个答案:

答案 0 :(得分:1)

您可以添加子查询和分析min()

select code, sr
from (
  select code, sr, min(sr) over (partition by code) as min_sr
  from (
    <your query>
  )
)
where sr = 0
or (sr = 1 and min_sr = 1)
order by sr;

对于每一行,子查询获得一个额外的列,其中包含所有行中该代码的最低SR。外部查询然后过滤那些,以便只有当该代码的最小值也为1时,才保留SR = 1的行;即SR = 0时该代码没有行。

使用您的虚拟数据:

CODE         SR
---- ----------
OF            0 
OF            0 
HA            0 
HA            0 
XY            1 
XY            1 
AC            1 

SQL Fiddle demo在您的数据中使用CTE,并在子查询中显示额外的analytic-min列。

您也可以将其简化为where sr = min_sr,但将其分为两个子句可能会使逻辑和规则更加清晰。

答案 1 :(得分:0)

也可以尝试以下操作,将上面的子查询放入WITH

WITH s AS (
    SELECT 'HA' as CODE,0 AS SR FROM DUAL UNION ALL
    SELECT 'HA' as CODE,0 AS SR FROM DUAL UNION ALL
    SELECT 'OF' as CODE,0 AS SR FROM DUAL UNION ALL
    SELECT 'AC' as CODE,1 AS SR FROM DUAL UNION ALL
    SELECT 'OF' as CODE,0 AS SR FROM DUAL UNION ALL
    SELECT 'OF' as CODE,1 AS SR FROM DUAL UNION ALL
    SELECT 'OF' as CODE,1 AS SR FROM DUAL UNION ALL
    SELECT 'XY' as CODE,1 AS SR FROM DUAL UNION ALL
    SELECT 'XY' as CODE,1 AS SR FROM DUAL UNION ALL
    SELECT 'HA' as CODE,1 AS SR FROM DUAL UNION ALL
    SELECT 'OF' as CODE,1 AS SR FROM DUAL )
SELECT code, sr FROM s s1 -- 's1' is the table alias
 WHERE s1.sr = 0
    OR ( s1.sr = 1
     AND NOT EXISTS ( SELECT 1 FROM s s2 -- 's2' is the table alias
                       WHERE s2.code = s1.code
                         AND s2.sr = 0 ) )

结果:

HA  0
HA  0
OF  0
OF  0
AC  1
XY  1
XY  1

我认为这是否比@Alex Poole的答案更具可读性。但它确实避免了分析功能。