【问题标题】:Conditional duplicate filtering query条件重复过滤查询
【发布时间】:2021-05-08 02:03:57
【问题描述】:

在 Oracle,我想在 TABLE 下面过滤为

COLUMNA COLUMNB COLUMNC
19 AAA PRIMARY
20 AAA PRIMARY
8 AAA SECONDARY
7 AAA SECONDARY
7 AAA PRIMARY
8 AAA SECONDARY
9 AAA SECONDARY

我的预期输出是

COLUMNA COLUMNB COLUMNC
19 AAA PRIMARY
20 AAA PRIMARY
7 AAA PRIMARY
9 AAA SECONDARY

逻辑是按 COLUMNA 和 COLUMNB 分组(请评估以下分组条件。)

  • 如果columnc 候选记录(按COLUMNACOLUMNB 分组)仅包含PRIMARYPRIMARY
  • 如果 columnc 候选记录(按 COLUMNACOLUMNB 分组)仅包含 SECONDARY take SECONDARY
  • 如果columnc候选记录(按COLUMNACOLUMNB分组)包括PRIMARYSECONDARY集,取PRIMARY
  • 如果columnc候选记录(按COLUMNACOLUMNB分组)包含重复的SECONDARY,则设置跳过记录。
  • 假设这一行有 100 列,所以我需要自己获取行。 MAX MIN 在这里不起作用。

我使用了几个row_number() 函数和where not exists,但都被遗忘了。

【问题讨论】:

  • 请解释逻辑。
  • 为什么结果集中是 9?
  • 已编辑条件。因为它必须在那里。如果我的专栏只有次要,它应该包含在@GordonLinoff
  • COLUMNA 8 值有 2 SECONDARY,它不在您的预期输出中。你清楚你想要什么吗?如果COLUMNB 总是具有相同的值,为什么你说逻辑是un COLUMNACOLUMNB
  • 是的@JaimeDrq。我不需要那些行,它必须被跳过。因为我在那里没有初选候选人,所以问题是加倍secondary

标签: sql oracle


【解决方案1】:

也许这个查询就是你要找的。正如我在评论中所说,根据您的描述还应包括 8 个

with your_data as (
  select 19 as columna, 'AAA' as columnb, 'PRIMARY' as columnc from dual union all
  select 20,'AAA','PRIMARY' from dual union all
  select 8 ,'AAA','SECONDARY' from dual union all
  select 7 ,'AAA','SECONDARY' from dual union all
  select 7 ,'AAA','PRIMARY' from dual union all
  select 8 ,'AAA','SECONDARY' from dual union all
  select 9 ,'AAA','SECONDARY' from dual
)
select distinct COLUMNA, COLUMNB, COLUMNC
from (
  select 
    COLUMNA, COLUMNB, COLUMNC, 
    count(DISTINCT COLUMNC) over (partition by COLUMNA) as x,
    count(COLUMNC) over (partition by COLUMNA) as y
  from your_data
  ) yd
where
  -- if columnc candidate rows includes only PRIMARY take PRIMARY
  (COLUMNC = 'PRIMARY' and x = 1)
  or
  -- if columnc candidate rows includes only SECONDARY take SECONDARY (just one record)
  (COLUMNC = 'SECONDARY' and x = 1 and y=1)
  or
  -- if columnc candidate rows includes PRIMARY and SECONDARY take PRIMARY
  (COLUMNC = 'PRIMARY' and x = 2)
order by 1

【讨论】:

  • if columnc candidate rows includes duplicate SECONDARY set skip record. 再次不应该包括 8 个,因为 COLUMNA 8 候选人总是有 SECONDARYCOLUMNC
  • 那为什么 9 是?
  • 因为 9 是单条记录。 SECONDARY 如果有单条记录,则包括在内。但它重复或重复三次,必须跳过。
  • 我已经修改了查询,现在达到你的目标了吗?也许你可以简化它,但我保持这种方式来显示与你的描述相关的每个过滤器
  • 因某种特殊原因而成熟?你明白了吗?
【解决方案2】:

看起来聚合可以满足您的需求:

SELECT COLUMNA, COLUMNB, MIN(COLUMNC)
FROM t
GROUP BY COLUMNA, COLUMNB
HAVING MIN(COLUMNC) = 'PRIMARY';

实际上,根据您的逻辑(但不是结果不一致),WHERE 就足够了:

SELECT COLUMNA, COLUMNB, MIN(COLUMNC)
FROM t
WHERE COLUMNC = 'PRIMARY'
GROUP BY COLUMNA, COLUMNB;

或整行:

SELECT t.*
FROM (SELECT t.*, 
             ROW_NUMBER() OVER (PARTITION BY Column1, Column2 ORDER BY Column1) as seqnum
      FROM t
      WHERE COLUMNC = 'PRIMARY'
     ) t
WHERE seqnum = 1;

【讨论】:

  • @ÖmrümÇetin。 . .那只需要一个HAVING 子句。
  • 想象这一行有 100 列,所以我需要自己获取行。 MAX MIN 在这里不起作用。我需要整行。现在 3 列...我可以将所有 98 列最小化。
【解决方案3】:

CInspired by @Jaime Drq 有以下解决方案。 易于理解和优化的查询。

WITH TABLE_VIEW AS (
SELECT /*+ ORDERED */ COLUMNA, COLUMNB, COLUMNC, ROW_NUMBER() OVER (PARTITION BY COLUMNA, COLUMNB ORDER BY COLUMNC ASC) CANDIDATERANKING
    FROM TABLE)
    SELECT * 
    FROM (
        SELECT COLUMNA, COLUMNB, COLUMNC, SUM(CANDIDATERANKING) PRIORITY
            FROM TABLE_VIEW TT
          GROUP BY COLUMNA, COLUMNB, COLUMNC)
    WHERE PRIORITY= 1;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-02-10
    • 2016-05-22
    • 1970-01-01
    • 2018-07-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多