来自行上多个表的值

时间:2009-07-17 12:22:02

标签: sql firebird

我有以下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查询为我做这个会更好。

5 个答案:

答案 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 JOINOracleSQL ServerPostgreSQL但不是MySQL)的系统中,第二个更好,如果布尔值均匀分布,i。即有很多TRUEFALSE,如果table3非常大。

如果分布存在偏差,如果table3中的行数少于table1table2,或者您使用的{{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