2016-05-03 24 views
7

我有三個表,是這樣的:PHP,MySQL - 從單個JOIN返回多個可識別的行?

*table1* 

id | val1 | val2 | val3 | val4 | val5 
1 | ... | ... | ... | ... | ... 
2 | ... | ... | ... | ... | ... 
3 | ... | ... | ... | ... | ... 
... etc 

*table2* 

id | som1 | som2 
1 | ... | ... 
2 | ... | ... 
3 | ... | ... 
... etc 

*table3* 

id | col1 | col2 
1 | ... | ... 
2 | ... | ... 
3 | ... | ... 
... etc 

其中col2在第三個表將總是包含來自val3單個值, val4val5從第一張桌子。第二個表僅包含在問題中以確保完整性,而不是問題。

查詢我有如下:

$db = new PDO(...); 
$stmt = $db->prepare("SELECT t2.som1 AS t2som1, 
          t1.val1 AS t1v1, 
          t1.val2 AS t1v2, 
          t1.val3 AS t1v3, 
          t1.val4 AS t1v4, 
          t1.val5 AS t1v5, 
          t3.col1 AS t3col1 
         FROM table1 t1 
          JOIN table2 t2 ON t1.val2 = t2.som2 
          JOIN table3 t3 ON t1.val3 = t3.col2 
         WHERE (t1.val4=:input OR t1.val5=:input) 
         AND (t1.val1=1 OR t1.val1=2)"); 

$stmt->execute(array('input'=>$inputVal)); 
$result = $stmt->fetchAll(); 

而且這部作品一種享受,完全按預期。

但是!

我不要只有需要t3col1對於t1.val3 = t3.col2。我還需要它t1.val4 = t3.col2t1.val5 = t3.col2

我可以構造線:

JOIN table3 t3 ON (t1.val3 = t3.col2 OR t1.val4 = t3.col2 OR t1.val5 = t3.col2) 

但是當時我不知道來獲得t3col1其價值。它只返回一個值,而不是全部三個。

看到我的問題!

我想有

SELECT t2.som1 AS t2som1, 
     ... 
     t3.col1 AS t3col1, // for condition t1.val3 = t3.col2 
     t3.col1 AS t3col2, // for condition t1.val4 = t3.col2 
     t3.col1 AS t3col3 // for condition t1.val5 = t3.col2 

可以這樣做?

澄清

IF val1val2val3都含有價值觀,我想一個返回行,從表3的所有三場比賽。不是三個單獨的行,除匹配列外全部相同。

This SQLFiddle是我不要想要的一個例子。請注意,除t3col1列外,所有內容均相同。這應該是一個單行,包含所有t3col1值。

/澄清

我想我可以加入表三個獨立的時間:

SELECT t2.som1 AS t2som1, 
     ... 
     t3.col1 AS t3col1 
     t4.col1 AS t3col2 
     t5.col1 AS t3col3 
FROM table1 t1 
    JOIN table2 t2 ON t1.val2 = t2.som2 
    JOIN table3 t3 ON t1.val3 = t3.col2 // for condition t1.val3 = t3.col2 
    JOIN table3 t4 ON t1.val4 = t3.col2 // for condition t1.val4 = t3.col2 
    JOIN table3 t5 ON t1.val5 = t3.col2 // for condition t1.val5 = t3.col2 
WHERE (...) 
AND (...) 

但我失去的性能做這種方式(即4聯接),而不是我怎麼了試圖做到這一點,只有2?

獎勵!

有時val3val4和/或val5將是空的(但col2從未空)。所有table3 JOIN需要爲LEFT JOIN s,對於那些空值的情況?

編輯1

按照您的要求,我已經把它架在SQLFiddle,但服務是打了小姐。

你可以找到它here

EDIT 2

我試圖加入表3中多次:

SELECT t2.som1 AS t2som1, 
     ... 
     t3.col1 AS t3col1 
     t4.col1 AS t3col2 
     t5.col1 AS t3col3 
FROM table1 t1 
    JOIN table2 t2 ON t1.val2 = t2.som2 
    JOIN table3 t3 ON t1.val3 = t3.col2 // for condition t1.val3 = t3.col2 
    JOIN table3 t4 ON t1.val4 = t3.col2 // for condition t1.val4 = t3.col2 
    JOIN table3 t5 ON t1.val5 = t3.col2 // for condition t1.val5 = t3.col2 
WHERE (...) 
AND (...) 

,並最終得到一排每場比賽。我應該有7個結果,並最終獲得超過90

val1將永遠有一個值,以及是否val2val3被填充每次都是不同的。但是,當所有三個人都有價值觀時,我不需要三個單獨的回報。相反,我只希望有一場比賽裏面有三場比賽。

編輯4(澄清爲3 ...)

多次join從EDIT 2是什麼結束了工作,這要歸功於西拉傑的答案。問題是,我用:

JOIN table3 t3 ON t1.val3 = t3.col2 
JOIN table3 t4 ON t1.val4 = t3.col2 
JOIN table3 t5 ON t1.val5 = t3.col2 

時,我應該用:

JOIN table3 t3 ON t1.val3 = t3.col2 
JOIN table3 t4 ON t1.val4 = t4.col2 
JOIN table3 t5 ON t1.val5 = t5.col2 

注意區別?這只是每個等號後面的t3.col2--他們需要引用正確的表格!其餘的都保持不變,鮑勃是你的阿姨!

+0

可以使用案例可以告訴你哪些值是用於第一個查詢加入構建您的查詢。 –

+1

爲您的示例數據提供SQL小提琴,然後很容易回答。 –

+0

請記住,如果這是一個'InnoDB'表,那麼必須在表模式中定義* first *字段作爲主鍵和外鍵。 –

回答

3

下面的查詢會給你的數據,你想:

SELECT t2.som1 AS t2som1, 
t1.val1 AS t1v1, 
t1.val2 AS t1v2, 
t1.val3 AS t1v3, 
t1.val4 AS t1v4, 
t1.val5 AS t1v5, 
t3.col1 AS t3col1, 
t3.col2 AS t3col2, 
CASE WHEN t1.val3 = t3.col2 THEN t3.col1 ELSE '' END AS 't3col11', 
CASE WHEN t1.val4 = t3.col2 THEN t3.col1 ELSE '' END AS 't3col21', 
CASE WHEN t1.val5 = t3.col2 THEN t3.col1 ELSE '' END AS 't3col31', 
CASE WHEN t1.val3 = t3.col2 THEN 't1col3' 
ELSE CASE WHEN t1.val4 = t3.col2 THEN 't1col4' ELSE 't1col5' 
END END AS ColumnName 
FROM table1 t1 
    JOIN table2 t2 ON t1.val2 = t2.som2 
    JOIN table3 t3 ON (t1.val3 = t3.col2 OR t1.val4 = t3.col2 OR t1.val5 = t3.col2) 
GROUP BY t2som1,t1v1, t1v2, t1v3, t1v4, t1v5 

最後一列是「的ColumnName」告訴你哪個T1列是值相匹配的一個。

編輯 - 使用左連接

SELECT t2.som1 AS t2som1, 
t1.val1 AS t1v1, 
t1.val2 AS t1v2, 
t1.val3 AS t1v3, 
t1.val4 AS t1v4, 
t1.val5 AS t1v5, 
t3.col1 AS t3col1, 
    t3.col1 AS t3col1, 
    t4.col1 AS t3col2, 
    t5.col1 AS t3col3 
FROM table1 AS t1 
LEFT JOIN table2 t2 ON t1.val2 = t2.som2 
LEFT JOIN table3 t3 ON t1.val3 = t3.col2 
LEFT JOIN table3 t4 ON t1.val4 = t4.col2 
LEFT JOIN table3 t5 ON t1.val5 = t5.col2 
+0

這給我可能是我想要的結果的三倍。我正在運行它(在這裏)(http://sqlfiddle.com/#!9/72835/11),你會看到第一(第一),第七(第七)和第十二(第12行)返回的行是相同的,除了't3col1'值。我需要將這些縮寫爲一行,並填充所有三個「t3col1」列。 – Birrel

+0

我在原帖中添加了「澄清」部分,描述了我想要返回的內容。 – Birrel

+0

所以你可以使用不同的或右邊的組? –