2012-03-29 77 views
0

我有來自測試的數據,有兩個部分的列表,分別叫做進入和退出。我需要在最後一次測試的部分進入但沒有出來的時候爲每個部分選擇測試值的總和。mysql通過比較兩個關係來選擇行的總和

IN LIST     OUT LIST     TEST 
+--------+-----------+ +--------+------------+ +------+-------+ 
| testid | in_partid | | testid | out_partid | | test | value | 
+--------+-----------+ +--------+------------+ +------+-------+ 
|  1 |  10 | |  1 |   10 | | 1 |  1 | 
|  1 |  20 | |  1 |   20 | | 2 | 10 | 
|  2 |  10 | |  2 |   10 | | 3 | 100 | 
|  2 |  20 | |  |   | |  |  | 
|  3 |  10 | |  3 |   10 | |  |  | 
|  3 |  20 | |  3 |   20 | |  |  | 
+--------+-----------+ +--------+------------+ +------+-------+ 

SUM是非常簡單的,但我可以把它限制在哪裏testid比testid更大的最後檢查,其中一部分去了,但沒有掉那些行?

在本例中,第10部分應彙總所有三個測試值,因爲它包含在所有列表中,但第20部分應該只返回測試3的值,如在測試2中它不包含在入出列表中。

partid sum(value) 
    10  111 
    20  100 

我可以使用mysql嗎,還是我需要包含php的混合?

+1

嵌套的SQL查詢或PHP。我更喜歡第二個,因爲第一個可能會很慢。 – kirilloid 2012-03-29 07:55:01

+0

我會遍歷每個partid以檢查它們是否包含在列表中。我想不出一個可以檢查所有可能性的mysql查詢。我也認爲你是一個例子,因爲當2-20會出現在列表中時會發生什麼,但是2-10不是?您可能需要獲得相同的輸出,但mysql查詢需要完全不同。 – Martin 2012-03-29 08:24:22

+0

感謝您的意見。也許我會遍歷這些部分,用一個空LEFT OUTER JOIN獲得最後一個不匹配的測試,然後從那裏繼續。 – Juhani 2012-03-29 08:58:09

回答

1

我認爲你的示例輸出在你的邏輯中是不正確的。我認爲PARTID 20應該返回101,因爲它是存在於列出了兩個測試1和3。假設我就在這,這個查詢應該返回了預期的效果

SELECT in_partid,SUM(value) 
FROM (
    SELECT DISTINCT in_partid,inl.testid 
    FROM in_list inl 
    INNER JOIN out_list outl ON in_partid=out_partid AND inl.testid=outl.testid 
    ) as tests_passed 
    INNER JOIN tests ON tests_passed.testid=test 
GROUP BY in_partid 

編輯:基於OP的評論我的以上假設是錯誤的,並且實際上是一項要求。因此,我認爲這是一個查詢,我認爲它符合要求:

SELECT tests_passed.in_partid,SUM(value) 
FROM (
    SELECT DISTINCT inl.in_partid,IFNULL(last_failed_test,0) as last_failed_test 
    FROM in_list inl LEFT JOIN (
     SELECT in_partid,MAX(inl.testid) as last_failed_test 
     FROM in_list inl 
     LEFT JOIN out_list outl ON in_partid=out_partid AND inl.testid=outl.testid 
     WHERE outl.testid IS NULL 
     GROUP BY in_partid 
    ) AS last_passed 
    ON inl.in_partid=last_passed.in_partid 
) as tests_passed 
INNER JOIN tests ON tests_passed.last_failed_test<test 
GROUP BY tests_passed.in_partid 

這將返回上面給出的示例結果的示例數據提供。

+0

不,這是正確的。我只對「異常」後的結果感興趣。優雅的建議,但不幸的是,這不是我所需要的。謝謝,不過。 – Juhani 2012-03-29 08:55:19

+0

@Juhani好吧,我已經更新了我的答案來處理這個要求。 – liquorvicar 2012-03-30 05:41:33

+0

完美地工作。你是一個巫師! – Juhani 2012-04-10 08:34:36