2015-12-03 105 views
-3

我有一個從整體 tableMysql的優化和爆炸

select 
    p, count(p) as frequency 
from 
    (SELECT 
     id, 
     CASE power1 <= power2 WHEN TRUE THEN CONCAT(power1,"-",power2) ELSE CONCAT(power2,"-",power1) 
     END p 
    FROM power 
    UNION 
    SELECT 
     id, 
     CASE power1<=power3 WHEN TRUE THEN CONCAT(power1,"-",power3) ELSE CONCAT(power3,"-",power1) END p 
    FROM power 
    UNION 
    SELECT 
     id, 
     CASE power1<=power4 WHEN TRUE THEN CONCAT(power1,"-",power4) ELSE CONCAT(power4,"-",power1) END p 
    FROM power 
    UNION 
    ............................................... 
    SELECT 
     id, 
     CASE power19<=power20 WHEN TRUE THEN CONCAT(power19,"-",power20) ELSE CONCAT(power20,"-",power19) 
     END p 
    FROM power) as b 
group by 
    p 
order by 
    frequency desc, p asc 
limit 
    0, 10 
  1. 顯示十大最拉數對下面的查詢我怎樣才能加以限制採取只是第100行按ID降序排列?該查詢會是這樣:

    ORDER BY ID LIMIT 0,100

    但我一直沒能適應它的上面。

  2. 代碼可以優化嗎?

  3. power1,power2是表中的值....如果我有一個類似於3,4,5,6的字符串然後爆炸「,」,然後power1變成3,power2變成4等?

我指的是表格式是這個樣子:

table2

以後編輯:

我的表是這樣的:

表:data

+----+----+-----+ 
| id | nr | set | 
+----+----+-----+ 
| 1 | 52 | 1 | 
| 2 | 47 | 1 | 
| 3 | 4 | 1 | 
| 4 | 3 | 1 | 
| 5 | 77 | 1 | 
| 6 | 71 | 1 | 
| 7 | 6 | 1 | 
| 8 | 41 | 1 | 
| 9 | 15 | 1 | 
| 10 | 79 | 1 | 
| 11 | 35 | 2 | 
| 12 | 50 | 2 | 
| 13 | 16 | 2 | 
| 14 | 1 | 2 | 
| 15 | 32 | 2 | 
| 16 | 77 | 2 | 
| 17 | 30 | 2 | 
| 18 | 7 | 2 | 
| 19 | 20 | 2 | 
| 20 | 28 | 2 | 
| .. | .. | ... | 
+----+----+-----+ 

我有一個像34360 ID

而下面的查詢:

SELECT 
    `n1`.`nr` AS `num_1`, 
    `n2`.`nr` AS `num_2`, 
    COUNT(1) AS `total` 

FROM (select * from data ORDER BY id DESC limit 0,1000) AS `n1` 

JOIN `data` AS `n2` 
    ON `n1`.`set` = `n2`.`set` AND `n1`.`nr` < `n2`.`nr` 

GROUP BY `n1`.`nr`, `n2`.`nr` 
ORDER BY `total` DESC 
LIMIT 20 

而且工作正常!

我想知道我怎麼能找出最長時間都沒有繪製在一起的數字對。每例如:

  • 1,42(一起,作爲一對)尚未繪製24繪製
  • 32,45-AS以及-尚未繪製22的一對平
+2

表面上,這裏有太多的錯誤,我不知道從哪裏開始。但正常化不是一個很好的開始。 – Strawberry

+0

正常化......這樣? http://i.stack.imgur.com/OsfKm.png – Xander

+0

不是。這與正常化相反。 – Strawberry

回答

2

考慮以下幾點:

未歸一:

id power1 power2 power3 power4 
1  4  9  10  16 
2  6  12  15  19 
3  2  4  6  7 
4  3  8  15  17 
5  2  10  11  14 
6  4  10  12  19 
7  1  4  9  11 

標準化:

id power value 
    1  1  4  
    1  2  9  
    1  3 10  
    1  4 16 
    2  1  6  
    2  2 12  
    2  3 15 
    2  4 19 
    3  1  2  
    3  2  4  
    3  3  6  
    3  4  7 
    4  1  3  
    4  2  8  
    4  3 15  
    4  4 17 
    5  1  2  
    5  2 10  
    5  3 11  
    5  4 14 
    6  1  4  
    6  2 10  
    6  3 12  
    6  4 19 
    7  1  1  
    7  2  4  
    7  3  9  
    7  4 11 

所以......

DROP TABLE IF EXISTS my_table; 

CREATE TABLE my_table 
(id INT NOT NULL 
,power INT NOT NULL 
,value INT NOT NULL 
,PRIMARY KEY(id,power) 
); 

INSERT INTO my_table VALUES 
(1,1,4),(1,2,9),(1,3,10),(1,4,16), 
(2,1,6),(2,2,12),(2,3,15),(2,4,19), 
(3,1,2),(3,2,4),(3,3,6),(3,4,7), 
(4,1,3),(4,2,8),(4,3,15),(4,4,17), 
(5,1,2),(5,2,10),(5,3,11),(5,4,14), 
(6,1,4),(6,2,10),(6,3,12),(6,4,19), 
(7,1,1),(7,2,4),(7,3,9),(7,4,11); 

SELECT LEAST(x.value,y.value)a -- LEAST/GREATEST is only necessary in the event that 
    , GREATEST(x.value,y.value) b -- power1 value may be greater than powerN value 
    , COUNT(*) freq 
    FROM my_table x 
    JOIN my_table y 
    ON y.id = x.id 
    AND y.power < x.power 
GROUP 
    BY LEAST(x.value, y.value) -- again only necessary if using LEAST/GREATEST above 
    , GREATEST(x.value,y.value) 
ORDER 
    BY freq DESC 
    , a 
    , b; 
+----+----+------+ 
| a | b | freq | 
+----+----+------+ 
| 4 | 9 | 2 | 
| 4 | 10 | 2 | 
| 12 | 19 | 2 | 
| 1 | 4 | 1 | 
| 1 | 9 | 1 | 
| 1 | 11 | 1 | 
| 2 | 4 | 1 | 
| 2 | 6 | 1 | 
| 2 | 7 | 1 | 
| 2 | 10 | 1 | 
| 2 | 11 | 1 | 
| 2 | 14 | 1 | 
| 3 | 8 | 1 | 
| 3 | 15 | 1 | 
| 3 | 17 | 1 | 
| 4 | 6 | 1 | 
| 4 | 7 | 1 | 
| 4 | 11 | 1 | 
| 4 | 12 | 1 | 
| 4 | 16 | 1 | 
| 4 | 19 | 1 | 
| 6 | 7 | 1 | 
| 6 | 12 | 1 | 
| 6 | 15 | 1 | 
| 6 | 19 | 1 | 
| 8 | 15 | 1 | 
| 8 | 17 | 1 | 
| 9 | 10 | 1 | 
| 9 | 11 | 1 | 
| 9 | 16 | 1 | 
| 10 | 11 | 1 | 
| 10 | 12 | 1 | 
| 10 | 14 | 1 | 
| 10 | 16 | 1 | 
| 10 | 19 | 1 | 
| 11 | 14 | 1 | 
| 12 | 15 | 1 | 
| 15 | 17 | 1 | 
| 15 | 19 | 1 | 
+----+----+------+ 
+0

謝謝,我可以做到這一點。但我不知道如何適應我的查詢。 – Xander

+0

@Xander再次,見上文。 – Strawberry

+1

一個很好的答案。值得一點imho點。對那些願意捲起袖子做正確的事 – Drew

0

雖然我@Strawberry完全同意關於標準化你的數據,以下是如何可能與您當前的數據結構做一個例子(未測試)。

SELECT CASE a.power_val <= b.power_val WHEN TRUE THEN CONCAT(a.power_val,"-",b.power_val) ELSE CONCAT(b.power_val,"-",a.power_val) END p, 
     COUNT(a.id) as frequency 
FROM 
(
    SELECT id,1 AS power_col, power1 AS power_val FROM power UNION 
    SELECT id,2, power2 FROM power UNION 
    SELECT id,3, power3 FROM power UNION 
    SELECT id,4, power4 FROM power UNION 
    SELECT id,5, power5 FROM power UNION 
    SELECT id,6, power6 FROM power UNION 
    SELECT id,7, power7 FROM power UNION 
    SELECT id,8, power8 FROM power UNION 
    SELECT id,9, power9 FROM power UNION 
    SELECT id,10, power10 FROM power UNION 
    SELECT id,11, power11 FROM power UNION 
    SELECT id,12, power12 FROM power UNION 
    SELECT id,13, power13 FROM power UNION 
    SELECT id,14, power14 FROM power UNION 
    SELECT id,15, power15 FROM power UNION 
    SELECT id,16, power16 FROM power UNION 
    SELECT id,17, power17 FROM power UNION 
    SELECT id,18, power18 FROM power UNION 
    SELECT id,19, power19 FROM power UNION 
    SELECT id,20, power20 FROM power 
    ORDER BY id DESC 
    LIMIT 2000 
) a 
INNER JOIN 
(
    SELECT id, 1 AS power_col, power1 AS power_val FROM power UNION 
    SELECT id, 2, power2 FROM power UNION 
    SELECT id,3, power3 FROM power UNION 
    SELECT id,4, power4 FROM power UNION 
    SELECT id,5, power5 FROM power UNION 
    SELECT id,6, power6 FROM power UNION 
    SELECT id,7, power7 FROM power UNION 
    SELECT id,8, power8 FROM power UNION 
    SELECT id,9, power9 FROM power UNION 
    SELECT id,10, power10 FROM power UNION 
    SELECT id,11, power11 FROM power UNION 
    SELECT id,12, power12 FROM power UNION 
    SELECT id,13, power13 FROM power UNION 
    SELECT id,14, power14 FROM power UNION 
    SELECT id,15, power15 FROM power UNION 
    SELECT id,16, power16 FROM power UNION 
    SELECT id,17, power17 FROM power UNION 
    SELECT id,18, power18 FROM power UNION 
    SELECT id,19, power19 FROM power UNION 
    SELECT id,20, power20 FROM power 
    ORDER BY id DESC 
    LIMIT 2000 
) b 
ON a.id = b.id 
AND a.power_col != b.power_col 
GROUP BY p 
ORDER BY frequency DESC, p ASC 
LIMIT 0,10 

注意使用規範化的數據結構可能會更快。

編輯

認爲像下面可能給你你所需要的。

大的子查詢是獲得每一個可能的組合(想法是也處理從未使用過的對),第一個數字小於第二個數字的一​​致性。然後再與數據表進行連接以獲得匹配的數字和相應的id字段。然後使用MIN獲得最小的ID: -

SELECT all_combo.num_1, 
     all_combo.num_2, 
     MIN(d1.id) 
FROM 
(
    SELECT  sub0.nr AS num_1, 
       sub1.nr AS num_2 
    FROM 
    (
     SELECT DISTINCT nr 
     FROM data 
    ) sub0 
    INNER JOIN 
    (
     SELECT DISTINCT nr 
     FROM data 
    ) sub1 
    WHERE sub0.nr < sub1.nr 
) all_combo 
LEFT OUTER JOIN data d1 ON all_combo.num_1 
LEFT OUTER JOIN data d2 ON all_combo.num_2 AND d1.set = d2.set 
GROUP BY all_combo.num_1, 
     all_combo.num_2 
+0

感謝您的回答。對我來說,在這個格式表上應用會更好。但你的代碼不起作用,我不知道問題出在哪裏。 – Xander

+0

完成一些小改動。你有一些示例數據和你期望的結果嗎? – Kickstart

+0

現在它正在嘔吐。我的桌子上有9000排。我怎樣才能在整個桌子上搜索?例如,我如何只搜索最後100個ID作爲例子。從你的例子我不明白究竟是什麼是LIMIT 2000. - – Xander