PHP,MySQL - 从单个JOIN返回多个可识别的行?

时间:2016-05-03 19:24:52

标签: php mysql join pdo

我有三张桌子,例如:

*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 始终包含来自第一个表格的val3val4val5的单个值。第二个表仅包含在完整性问题中,并不是问题。

我的查询如下:

$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();

这就像预期的那样有效。

BUT!

对于t3col1 我还需要t1.val3 = t3.col2t1.val4 = t3.col2

我可以构建这一行:

t1.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 val1val2都包含值,我希望返回单个行,其中包含来自table3的所有三个匹配项。不是三个单独的行,除了匹配列之外都是相同的。

This SQLFiddle是我不想想要的一个例子。请注意,除val3列之外,所有内容都相同。这应该是一行,包含所有t3col1值。

/澄清

我估计我可以分三次加入桌子:

t3col1

但我是否会以这种方式失去表现(即4个JOINS),与我试图做的相反,仅仅是2?

加成!

有时 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 (...) val3和/或val4将为空(但val5 从不为空)。对于那些空值的情况,所有table3 JOIN都需要col2 s吗?

编辑1

根据您的要求,我已经在SQLFiddle中进行了设置,但是这项服务非常突然。

你可以找到它here

编辑2

我多次尝试加入table3:

LEFT JOIN

并最终为每场比赛获得一排。我应该有7个结果,最终得到超过90个。

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 (...) 将始终具有值,并且每次填充val1val2是否都不同。但是当这三个人都有价值观时,我不想要三个单独的回报。相反,我只想要一个包含所有三个匹配的回归。

编辑4(澄清是3 ......)

由于Siraj的回答,来自EDIT 2的多个JOIN 最终起作用了。问题是我用过:

val3

当我应该使用时:

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 - 他们需要引用正确的表格!其余的都保持不变,鲍勃是你的阿姨!

1 个答案:

答案 0 :(得分: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