来自一个表ORACLE SQL中的多个字段的不同值

时间:2011-07-22 10:58:56

标签: sql oracle

如何只使用一个请求从一个表中的多个字段中获取不同的值。

选项1

SELECT WM_CONCAT(DISTINCT(FIELD1)) FIELD1S,WM_CONCAT(DISTINCT(FIELD2)) FIELD2S,..FIELD10S
  FROM TABLE;

WM_CONCAT有限

选项2

select DISTINCT(FIELD1) FIELDVALUE, 'FIELD1' FIELDNAME
       FROM TABLE
UNION
select DISTINCT(FIELD2) FIELDVALUE, 'FIELD2' FIELDNAME
       FROM TABLE
... FIELD 10

太慢了

5 个答案:

答案 0 :(得分:2)

对于我的问题,我有

WL1   ...   WL2   ...  correlation
A            B             0.8
B            A             0.8
A            C             0.9
C            A             0.9

如何消除此表中的对称性?

    select WL1, WL2,correlation from
    table
    where least(WL1,WL2)||greatest(WL1,WL2) = WL1||WL2
    order by WL1

这给出了

WL1   ...   WL2   ...  correlation
A            B             0.8
A            C             0.9

:)

答案 1 :(得分:1)

SQL中最好的选项是UNION,但您可以通过取出distinct个关键字来保存一些效果:

select FIELD1 FROM TABLE
UNION
select FIELD2 FROM TABLE

UNION提供了两个表中的唯一集合,因此在这种情况下,distinct是多余的。根本没有办法以不同的方式编写此查询以使其执行得更快。没有神奇的公式可以让你更快地搜索200,000多行。它必须两次搜索表格的每一行并对唯一性进行排序,这正是UNION将要做的事情。

你可以让它更快的唯一方法是在两个字段(可能)上创建单独的索引,或者削减你正在搜索的数据集。

或者,如果你这么做并且很少添加新字段,你可以使用物化视图存储结果,只定期刷新它。

顺便提一下,您的第二个查询似乎没有按照您的意愿执行。 Distinct始终适用于select部分中的所有列,因此带有字段名称的常量将导致查询始终为两列返回单独的行。


我想出了另一种方法,实验上看起来似乎要快一点。在影响中,这允许我们交换一个全表扫描以进行笛卡尔连接。在大多数情况下,我仍然会选择使用union,因为查询正在做的更为明显。

SELECT DISTINCT CASE lvl WHEN 1 THEN field1 ELSE field2 END
FROM              table
       CROSS JOIN (SELECT     LEVEL lvl
                   FROM       DUAL
                   CONNECT BY LEVEL <= 2);

同样值得补充的是,我在一个没有包含800,000行的有用索引的表上测试了两个查询,大约需要45秒(返回145,000行)。但是,大部分时间用于实际获取记录,而不是运行查询(查询耗时3-7秒)。如果您获得了相当数量的行,则可能只是导致您遇到性能问题的行数。

答案 2 :(得分:1)

如果您扫描数据中的小范围(未完整扫描整个表格),您可以使用WITH来优化查询 e.g:

WITH a AS 
(SELECT field1,field2,field3..... FROM TABLE WHERE condition)
SELECT field1 FROM a
UNION   
SELECT field2 FROM a
UNION   
SELECT field3 FROM a
.....etc

答案 3 :(得分:0)

当您从多个列中获取不同的值时,它将不会返回数据表。如果您认为以下数据

Column A            Column B
10 50
30 50
10 50

当你得到不同的时候,它将是第一列的2行和第2列的1行。它根本行不通。

答案 4 :(得分:0)

这样的事情?

SELECT 'FIELD1',FIELD1, 'FIELD2',FIELD2,...
FROM TABLE
GROUP BY FIELD1,FIELD2,...