我有三个表,比如:
*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
、val4
或 val5
来自第一个表。第二个表只是为了完整性而包含在问题中,而不是问题。
我的查询如下:
$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.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
这可以做到吗?
澄清
IF val1
、val2
和 val3
都包含值,我希望返回一个单个行,其中表 3 中的所有三场比赛。不是三个单独的行,它们除了匹配列外都是相同的。
This SQLFiddle是我不想要的例子。请注意,除了 t3col1
列外,所有内容都是相同的。这应该是一行,包含所有 t3col1
值。
/澄清
我估计我可以分别加入表 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 (...)
但我这样做是否会降低性能(即 4 个 JOINS),这与我尝试做的方式相反,仅使用 2 个?
奖金!
有时 val3
、val4
和/或 val5
将为空(但col2
从不为空)。对于那些具有空值的情况,是否所有 table3 JOIN 都需要是 LEFT JOIN
?
编辑 1
根据您的要求,我已经在 SQLFiddle 中进行了设置,但该服务时断时续。
你可以找到它here
编辑 2
我多次尝试连接 table3:
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
总会有一个值,val2
和 val3
是否填充每次都不同。但是当这三个都有值时,我不希望它有三个单独的返回。相反,我只想要一个包含所有三个匹配项的返回值。
编辑 4(澄清是 3...)
由于 Siraj 的回答,来自 EDIT 2 的 multiple JOINs 最终起作用了。问题是我使用了:
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
- 他们需要引用正确的表格!其余的都保持不变,鲍勃是你的阿姨!
最佳答案
下面的查询会给你你想要的数据:
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
关于PHP、MySQL - 获取从单个 JOIN 返回的多个可识别行?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37012721/