【问题标题】:Oracle SQL: Retrieving a record more than onceOracle SQL:多次检索记录
【发布时间】:2018-12-31 19:28:27
【问题描述】:

我正在使用 Oracle 11,并且希望能够在查询中检索多个记录,这将非常方便地为我的代码的下一部分保存。

让我们考虑这个 SQL 语句:

SELECT ID, NAME FROM PEOPLE WHERE NAME IN ('Alice', 'Bob', 'Alice');

它返回这个数据:

| 1 | Alice | 
| 2 | Bob   |

我真正想做的是取消该列表的唯一性,并按照给定的顺序返回具有重复项的记录。所以上面的语句是:

| 1 | Alice | 
| 2 | Bob   |
| 1 | Alice | 

我很欣赏 Oracle 经过优化以消除这样的重复,我可以在之后重新使用数据,将其保存在存储对象中并按名称检索等。我只是想知道是否有办法做到这一点在数据库本身上。

【问题讨论】:

  • 如果你只有这三个名字,你可以做三个不同的选择和一个联合。 Union all 不会删除重复项。
  • @RigertaDemiri 这是一个有趣的解决方案。不幸的是,我需要将其扩展到更多的记录。
  • @BarbarosÖzhan select distinct 仍然返回两条记录。因为行是相同的。
  • 使用子查询而不是IN 并设置JOIN。如果您希望输出中有三行,则输入中的某处必须有三行。
  • 对不起,你想要重复,好的,为此@RigertaDemiri 的建议很好。

标签: sql oracle select duplicates


【解决方案1】:

Oracle 有几个方便的内置函数,它们返回参数列表,然后您可以将其转换为一个表并加入它。在您的情况下,odcivarchar2list 可用于返回varchar2s 的列表:

SELECT p.*
FROM   TABLE(sys.odcivarchar2list('Alice', 'Bob', 'Alice')) dups
JOIN   people p ON p.name = dups.column_value*

【讨论】:

    【解决方案2】:

    在下方查询重复记录

    select x.id,x.name from (
      select a.id,a.name from people a where a.name in ('Alice')
      union all
      select a.id,a.name from people a where a.name in ('Bob')
      union all
      select a.id,a.name from people a where a.name in ('Alice')
    ) x
    

    【讨论】:

      【解决方案3】:

      迟到但只是想补充一下,您可以使用传统的表格表达方式:

      select p.id, p.name
        from (
          select 'Alice' as name from dual
          union all select 'Bob' from dual
          union all select 'Alice' from dual
        ) searched s
        join people p on p.name = s.name;
      

      【讨论】:

        【解决方案4】:

        这是另一个想法:

        WITH cteNumbers as (SELECT LEVEL AS N
                              FROM DUAL
                              CONNECT BY LEVEL <= 2),
             PEOPLE AS (SELECT 'Bob' AS NAME, 111 AS EMPID FROM DUAL UNION ALL
                        SELECT 'Carol' AS NAME, 222 AS EMPID FROM DUAL UNION ALL
                        SELECT 'Ted' AS NAME, 333 AS EMPID FROM DUAL UNION ALL
                        SELECT 'Alice' AS NAME, 444 AS EMPID FROM DUAL)
        SELECT *
          FROM PEOPLE p
          CROSS JOIN cteNumbers
          WHERE 1 = CASE
                      WHEN NAME = 'Alice' THEN 1
                      WHEN NAME = 'Bob' AND N = 1 THEN 1
                      WHEN NAME = 'Ted' AND N < 4 THEN 1
                      WHEN NAME = 'Carol' AND N = 3 THEN 1
                      ELSE 0
                    END
          ORDER BY NAME, N
        

        基本上,使用 cteNumbers 生成数字列表(在本例中,从 1 到 2 - 调整 CONNECT BY LEVEL 条件以控制生成多少数字),然后在 WHERE 中使用 CASE 表达式子句来控制选择特定记录的重复的情况。

        SQLFiddle here

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2012-04-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-03-23
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多