2012-01-03 37 views
8

我有一個表有6列:查看重複行的所有數據在Oracle

  • id
  • name
  • type_id
  • code
  • lat
  • long

前三個是必需的。 ID是私鑰,自動插入一個序列。

我有一些行是重複的,定義爲nametype_id是相等的,但我想查看所有的數據。我可以簡單地找到這些誘惑:

SELECT name 
     , type_id 
FROM table1 
GROUP BY name 
     , type_id 
HAVING COUNT(*) > 1 

但實際上查看所有的信息讓我困惑。我知道這應該很簡單,但我在這裏打了一堵牆。

回答

15

您可以隨時使用GROUP BY/HAVING查詢的IN子句。這是有效的,並且相對簡單,但如果重複行的數量相對較大,則效率可能不是特別高。

SELECT * 
    FROM table1 
WHERE (name, type_id) IN (SELECT name, type_id 
          FROM table1 
          GROUP BY name, type_id 
          HAVING COUNT(*) > 1) 

使用分析函數以避免再次擊中表格通常會更高效。

SELECT * 
    FROM (SELECT id, 
       name, 
       type_id, 
       code, 
       lat, 
       long, 
       count(*) over (partition by name, type_id) cnt 
      FROM table1) 
WHERE cnt > 1 

取決於你計劃的數據,多少特定行的副本有可能是做的,你可能也想加入table1本身得到的單行數據

SELECT a.name, 
     a.type_id, 
     a.id, 
     b.id, 
     a.code, 
     b.code, 
     a.lat, 
     b.lat, 
     a.long, 
     b.long 
    FROM table1 a 
     JOIN table1 b ON (a.name = b.name AND 
         a.type_id = b.type_id AND 
         a.rowid > b.rowid) 
+0

我的第一個想法是第一個查詢,但我不知道你是否可以在IN子句中使用兩列。我想我應該試試。謝謝。 – Marc 2012-01-03 21:22:35

1
SELECT * 
FROM table1 t1 
WHERE (t1.name,t1.type_id) in (SELECT DISTINCT name 
               , type_id 
           FROM  table1 
           GROUP BY name, type_id 
           HAVING COUNT(*) > 1) 

會這樣做。

HTH

1

你可以做一個自聯接在桌子上找到所有對重複的:

SELECT 
    a.name name 
, a.type_id type_id_a 
, a.code code_a 
, a.lat  lat_a 
, a.long long_a 
, b.code code_b 
, b.lat  lat_b 
, b.long long_b 
FROM table1 a 
JOIN table1 b 
ON a.name = b.name 
AND a.type_id = b.type_id 
AND a.ROWID > b.ROWID 

爲了確保行不匹配本身和每對只輸出一次,我添加了a.ROWID > b.ROWID,它適用於Oracle。如果您使用不同的數據庫,您將需要一種不同的方式將它們分開。

+0

想必,你想要一個額外的連接條件,以確保該行從'A'和'B'實際上是不同的行返回。就像'AND a.id> b.id'或'AND a。rowid> b.rowid' – 2012-01-03 21:07:32

+0

謝謝,我更新了答案。 – 2012-01-03 21:16:50

0

這仍然沒有找到雙打如果比較的領域之一,具有空值。 爲了獲得這些,我使用nvl來將比較字段中的NULL與我知道的值不能在該表/字段中出現的值相關聯。

-2

只要使NULLS 0 ...

...使用NVL功能。