2016-05-03 25 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

所以你可以使用不同的或右边的组? –