Oracle SQL:多次检索记录

时间:2018-07-24 08:37:58

标签: sql oracle select duplicates

我正在使用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经过优化以消除这种重复,并且之后可以重用数据,将其保存在存储对象中并按名称进行检索等。我只是想知道是否有办法做到这一点在数据库本身上。

4 个答案:

答案 0 :(得分:4)

Oracle有几个方便的内置函数,这些函数返回参数列表,然后您可以将其转换为表并加入该表。就您而言,odcivarchar2list可用于返回varchar2 s的列表:

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

答案 1 :(得分:3)

下面查询重复的记录

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

答案 2 :(得分:1)

晚聚会但只想添加即可使用传统的表格表达式:

LIMIT = 3
result = 0.12345
print("Result = {:.{}f}".format(result, LIMIT))  # 0.123

答案 3 :(得分:1)

这是另一个主意:

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条件以控制生成多少个数字),然后在其中使用CASE表达式WHERE子句控制选择特定记录重复的情况。

SQLFiddle here