如何在Oracle中的表中显示非重复值?

时间:2014-05-12 07:11:07

标签: sql oracle

我在Oracle的用户HR下有一个包含9列的表。所有列都是数字类型。我需要显示非重复值,同时省略重复的值,但我不知何故试图达到我想要的输出。

CREATE TABLE HR.CUSTOMERS
(
  ID  NUMBER(4),
  PHONE1       NUMBER(8),
  PHONE2       NUMBER(8),
  PHONE3       NUMBER(8),
  PHONE4       NUMBER(8),
  PHONE5       NUMBER(8),
  PHONE6       NUMBER(8),
  PHONE7       NUMBER(8),
  PHONE8       NUMBER(8)
)

ID    PHONE1   PHONE2   PHONE3   PHONE4   PHONE5   PHONE6   PHONE7   PHONE8
1000  12345678 23456781 34567812 45678123 56781234 67812345 78123456 81234567
2000  11111111 11111111 33333333 44444444 55555555 66666666 77777777 88888888
3000  11111111 11111111 11111111 22222222          22222222     

实施例: ID 1000不包含重复.... ID 2000包含2" 11111111"重复.... ID 3000包含3" 11111111"重复和2" 22222222"重复....

所需的输出如下:

ID    PHONE1   PHONE2   PHONE3   PHONE4   PHONE5   PHONE6   PHONE7   PHONE8
1000  12345678 23456781 34567812 45678123 56781234 67812345 78123456 81234567
2000  11111111          33333333 44444444 55555555 66666666 77777777 88888888
3000  11111111                   22222222

在我从这里搜索的帮助中,我可以获得重复计数的数量。但是,我一直试图从这里继续前进到所需的输出。

SELECT id,testField,
                COUNT(testField) AS fieldCount
           FROM (
SELECT id, phone1 AS testField
FROM customers
UNION ALL
SELECT id, phone2 AS testField
FROM customers
UNION ALL
SELECT id, phone3 AS testField
FROM customers
UNION ALL
SELECT id, phone4 AS testField
FROM customers
UNION ALL
SELECT id, phone5 AS testField
FROM customers
UNION ALL
SELECT id, phone6 AS testField
FROM customers
UNION ALL
SELECT id, phone7 AS testField
FROM customers
UNION ALL
SELECT id, phone8 AS testField
FROM customers
) 
GROUP BY id,testField
ORDER BY id;

我尝试的结果就在这里。 FIELDCOUNT超过1表示存在重复。

ID      TESTFIELD   FIELDCOUNT
1000    12345678    1
1000    23456781    1
1000    34567812    1
1000    45678123    1
1000    56781234    1
1000    67812345    1
1000    78123456    1
1000    81234567    1
2000    11111111    2
2000    33333333    1
2000    44444444    1
2000    55555555    1
2000    66666666    1
2000    77777777    1
2000    88888888    1
3000    11111111    3
3000    22222222    2
3000        0

2 个答案:

答案 0 :(得分:2)

我担心你能用这个数据模型做的最好的事情是:

SELECT
  id,
  phone1,
  CASE WHEN phone2 NOT IN ( phone1 ) THEN phone2 END AS phone2,
  CASE WHEN phone3 NOT IN ( phone1, phone2 ) THEN phone3 END AS phone3,
  CASE WHEN phone4 NOT IN ( phone1, phone2, phone3 ) THEN phone4 END AS phone4
  -- continue
FROM customers;

SQL Fiddle上的示例返回:

|   ID |   PHONE1 |   PHONE2 |   PHONE3 |   PHONE4 |
|------|----------|----------|----------|----------|
| 1000 | 12345678 | 23456781 | 34567812 | 45678123 |
| 2000 | 11111111 |   (null) | 33333333 | 44444444 |
| 3000 | 11111111 |   (null) |   (null) | 22222222 |

如果这是一个选项,请尝试将模型规范化为以下内容:

id    phone_number  phone_number_index (if necessary)
1000  12345678      1
1000  23456781      2
2000  11111111      1

另外,一个电话 - "号码"通常不会存储为NUMBER而是存储为VARCHAR2,因为必须存储+/或空格等字符的概率远高于提升的可能性所有电话号码减10%或其他计算。

答案 1 :(得分:0)

如果您可以将电话号码列表列为一行,则可以尝试使用此类

select id, listagg(phone, '; ') within group (order by id) phone_list
from (
select distinct id, phone
from customers
unpivot include nulls (phone for phonetype in  (PHONE1, PHONE2, PHONE3, PHONE4, PHONE5, PHONE6, PHONE7, PHONE8))
) group by id