我有以下3个表
Table1
ID | NAME
-----------
1 | X
2 | Y
3 | Z
Table2
ID | NAME
-----------
1 | A
2 | B
3 | C
Table3
ID | P (Boolean field) | Other cols
1 | True ...
2 | True....
1 | False
现在我需要对table3进行查询,该查询必须执行以下操作:
显示table1和table2的名称字段。但我的问题是 如果table3上的字段P为真,我希望它显示table2的字段的名称,其中table2.id = table3.id但是如果它为false我需要它来读取table1的名称字段的名称,其中table1.id = table3.id。
显示结果的程序是一个桌面应用程序,我可以用一些程序或其他东西来显示它们,但如果我有一个SQL查询为我做这个会更好。
答案 0 :(得分:3)
此:
SELECT CASE WHEN p
THEN
(
SELECT name
FROM table2 t2
WHERE t2.id = t3.id
)
ELSE
(
SELECT name
FROM table1 t1
WHERE t1.id = t3.id
)
END
FROM table3 t3
,或者这个:
SELECT CASE WHEN p THEN t2.name ELSE t1.name END
FROM table3 t3
JOIN table1 t1
ON t1.id = t3.id
JOIN table1 t2
ON t2.id = t3.id
在能够执行HASH JOIN
(Oracle
,SQL Server
,PostgreSQL
但不是MySQL
)的系统中,第二个更好,如果布尔值均匀分布,i。即有很多TRUE
和FALSE
,如果table3
非常大。
如果分布存在偏差,如果table3
中的行数少于table1
或table2
,或者您使用的{{1> }}
<强>更新强>
如果大多数字段都是false,则以下查询可能是最好的:
MySQL
此处的子查询仅用作后备,并且仅针对罕见的SELECT CASE WHEN p THEN
(
SELECT name
FROM table2 t2
WHERE t2.id = t3.id
)
ELSE t1.name
END AS cname
FROM table3 t3
JOIN table1 t1
ON t1.id = t3.id
ORDER BY
cname
值执行。
更新2:
我无法在Firebird上查看它,但在大多数系统上,上面查询中的TRUE
语法都可以。如果没有,请将查询包装到内联视图中:
ORDER BY
,虽然它可能会妨碍性能(至少在它SELECT cname
FROM (
SELECT CASE WHEN p THEN
(
SELECT name
FROM table2 t2
WHERE t2.id = t3.id
)
ELSE t1.name
END AS cname
FROM table3 t3
JOIN table1 t1
ON t1.id = t3.id
) q
ORDER BY
cname
中)。
答案 1 :(得分:1)
你可以使用
select if(P, t1.name, t2.name) ...
答案 2 :(得分:0)
SELECT `id`, IF(`table3`.`P`, `table2`.`name`, `table1`.`name`) AS `name`
FROM `table3`
JOIN `table2` USING (`id`)
JOIN `table1` USING (`id`)
答案 3 :(得分:0)
可能不是一个选项,但有时重新设计架构将解决很多问题。任何执行每行函数的解决方案都应该仔细检查非常以解决性能问题(实际上任何查询应该持续监视性能问题,尤其是每行函数问题)。
考虑将表1和表2组合在一起:
Table1And2:
Id | IsTable2 | Name
---+----------+-----
1 | false | X
2 | false | Y
3 | false | Z
1 | true | A
2 | true | B
3 | true | C
Primary key (Id,IsTable2)
Possible index on (IsTable2) as well, depending on DBMS.
Table3:
Id | P (Boolean field) | OtherCols
---+--------------------+----------
1 | true |
2 | true |
1 | false |
然后你的查询变得相对简单(几乎肯定是快速的):
select a.Id, b.Name, a.OtherCols
from Table3 a, Table1And2 b
where a.Id = b.Id and a.P = b.isTable2
性能问题通常只涉及大型表,大型机大小,其中500万行被视为配置表:-)可能没有必要处理您正在处理的表,但它是一个有用的工具在军械库中。
答案 4 :(得分:0)
它和mysql中的这个查询一样简单。
SELECT T3.ID,
T3.P,
IF(T3.P = true, T2.NAME, T1.NAME) AS NAME
FROM Table3 T3
LEFT JOIN Table2 T2 ON T2.ID = T3.ID
LEFT JOIN Table1 T1 ON T1.ID = T3.ID