SQL

2013-08-19 90 views
1

SQL

CREATE TABLE a 
(id INT PRIMARY KEY, 
p1 INT, p2 INT, p3 INT, .. , p15 INT) 

P(n)的取值在這裏,我們比較的條目比較條目與型動物的參數從0到2

我得與parameteres的唯一組合的所有條目。這並不困難,所以我創建了這樣的表格

CREATE TEMPORARY TABLE b AS 
(SELECT 
     t1.id, 
     t2.p1, t2.p2, t2.p3, t2.p4, t2.p5, t2.p6, t2.p7, t2.p8, 
     t2.p9, t2.p10, t2.p11, t2.p12, t2.p13, t2.p14, t2.p15 
FROM 
(
    SELECT 
     p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15 
    FROM 
     a 
    GROUP BY 
     p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11, p12, p13, p14, p15 
    HAVING COUNT(*) = 1 
)t2 
LEFT JOIN a t1 on 
t2.p1 = t1.p1 
AND t2.p2 = t1.p2 
AND t2.p3 = t1.p3 
AND t2.p4 = t1.p4 
AND t2.p5 = t1.p5 
AND t2.p6 = t1.p6 
AND t2.p7 = t1.p7 
AND t2.p8 = t1.p8 
AND t2.p9 = t1.p9 
AND t2.p10 = t1.p10 
AND t2.p11 = t1.p11 
AND t2.p12 = t1.p12 
AND t2.p13 = t1.p13 
AND t2.p14 = t1.p14 
AND t2.p15 = t1.p15) 

在這裏,我們得到了獨特的參數組合。

下一步是針對表A中的每條記錄查找表B中的所有記錄,這些記錄相差一個,兩個和三個參數。記錄由單個參數差異應該不超過一個,記錄兩個不同的參數應用不超過兩個等

例如更多:

id | p(n)   
-----+----------------  
1 |000000000000000  
2 |000000000000001 

我創建的形式的一個臨時表

CREATE TEMPORARY TABLE c AS 
(
SELECT 
    cnt, id1, id2 
FROM 
(
    SELECT 
     (t1.p1 = t2.p1)+(t1.p2 = t2.p2) 
     +(t1.p3 = t2.p3) +(t1.p4 = t2.p4) +(t1.p5 = t2.p5) 
     +(t1.p6 = t2.p6) +(t1.p7 = t2.p7) +(t1.p8 = t2.p8) 
     +(t1.p9 = t2.p9) +(t1.p10 = t2.p10) +(t1.p11 = t2.p11) 
     +(t1.p12 = t2.p12) +(t1.p13 = t2.p13) +(t1.p14 = t2.p14) 
     +(t1.p15 = t2.p15) AS cnt, 
     t1.id id1, 
     t2.id id2 
    FROM 
     b AS t1, 
     a AS t2 
) 
WHERE 
    (cnt BETWEEN 12 AND 14) 
    AND (id1 < id2) 
) 

在這裏,我得到一個表對有不同的1,2和3參數

但我碰到了表中的問題條目相當多的約100,000條目。該表格太大(在家用PC上處理過的數據)並且創建表格的時間很長。

也許這是獲得一切的唯一方法,但任何人都可以有解決這個問題的分析方法比蠻力夫婦(也許不是SQL)的任何想法。當然,這將得到更快的解決...

任何提示將不勝感激!謝謝!

回答

1

如果你想只用獨特的條目的表格,你可以創建一個所有列第二表作爲一個複合主鍵的一部分:

CREATE TABLE b (
(id INT, p1 INT, p2 INT, p3 INT, .. , p15 INT) 
PRIMARY KEY (p1, p2, p3, .. , p15)) 
IGNORE SELECT * FROM a; 
+0

不太什麼,我需要...... 我必須擺脫所有具有的參數相同的組合條目和這樣不僅能消除重複 –

0

可能這不是你的問題,一個完整的答案,但如果我有這樣的任務,我會嘗試的第一件事是推廣一個查詢。當我必須指定3個以上相似的列並且非常容易出錯時,對我來說非常困難。
所以,我建議儘量列轉動你行和比較的差異,像(選擇任何你喜歡的支點方法,我只是用聯盟sqlfiddle,您可以使用hstore這裏發佈PostgreSQL columns to rows with no explicilty specifying column names/columns):

with cte1 as (
    select id, 'p1' as name, p1 as value from a 
    union all 
    select id, 'p2' as name, p2 as value from a 
    union all 
    select id, 'p3' as name, p3 as value from a 
    union all 
    select id, 'p4' as name, p4 as value from a 
), cte2 as (
    select 
     c1.id, sum(case when c1.value = c2.value then 0 else 1 end) as diff 
    from cte1 as c1 
     inner join cte1 as c2 on c2.id <> c1.id and c2.name = c1.name 
    group by c1.id, c2.id 
) 
select 
    id, diff, count(*) as cnt 
from cte2 
group by id, diff 
order by id, diff 

我想你的桌子沒有重複,你可以預先消除它們。

sql fiddle demo

更新
我不知道這是否會幫助你,BU看看這個問題PostgreSQL, find strings differ by n characters,我問它來儘量幫你,檢查歐文Brandstetter修改答案那裏。

我用不同的方法爲你創建了一個sql fiddle demo,看起來像使用levenshtein是最快的一個,但它並沒有比原來的方法快得多。

+0

是的,這是一個更好的解決方案,但問題依舊。 MySQL查詢第二個小時(100,000個條目) –

+0

@AlexanderKhe所以你正在使用MySQL? –

+0

是的,但不一定。我試圖使用MS SQL Server,但結果是相同的 –