问题简报:
我有一个名为“Customers”的超类表和两个继承自Customers的子表,名为“Person”和“Company”。因此,客户实体与“人”或“公司”具有一对一的关系。
(客户只能是“人”或“公司”,但两者都不能)
这表示如下:
Customer Person Company
+-------+------+------+ +-------+------+------+ +-------+------+------+
| cID| col2| col3| | cID| fname| sname| | cID| name| col3|
+-------+------+------+ +-------+------+------+ +-------+------+------+
|1 |? |? | |1 |JJ |AZ | |4 |ABCD |? |
+-------+------+------+ +-------+------+------+ +-------+------+------+
|2 |? |? | |2 |CC |LL | |5 |BCDE |? |
+-------+------+------+ +-------+------+------+ +-------+------+------+
|3 |? |? | |3 |OO |BB | |6 |CDEF |? |
+-------+------+------+ +-------+------+------+ +-------+------+------+
|4 |? |? | |7 |JK |NN | |8 |DEFG |? |
+-------+------+------+ +-------+------+------+ +-------+------+------+
|5 |? |? | |9 |RR |LW | |... |EFGH |? |
+-------+------+------+ +-------+------+------+ +-------+------+------+
|6 |? |? | |10 |GN |QN | |... |FGHI |? |
+-------+------+------+ +-------+------+------+ +-------+------+------+
|7 |? |? | |... |XC |YU | |... |GHIJ |? |
+-------+------+------+ +-------+------+------+ +-------+------+------+
|8 |? |? |
+-------+------+------+
|9 |? |? |
+-------+------+------+
|10 |? |? |
+-------+------+------+
|... |? |? |
+-------+------+------+
意图&尝试:
我想要查询数据库,以便我可以从Customer表中选择ID,加入Person和Company以检索name属性。
以下是我的尝试:
SELECT tc."cust_id",
CONCAT(tp."forename", ' ', tp."surname") AS "name",
tcp."name"
FROM "tbl_customer" AS tc
LEFT JOIN "tbl_person" AS tp
ON tc."cust_id" = tp."cust_id"
LEFT JOIN "tbl_company" AS tcp
ON tc."cust_id" = tcp."cust_id"
执行上面的SQL给出了以下结果,而右边是我想要实现的目标:
Result Result
+-------+------+------+ +-------+------+
| cID| name| name| | cID| name|
+-------+------+------+ +-------+------+
|1 |JJAZ |null | |1 |JJAZ |
+-------+------+------+ +-------+------+
|2 |CCLL |null | |2 |CCLL |
+-------+------+------+ +-------+------+
|3 |OOBB |null | |3 |OOBB |
+-------+------+------+ +-------+------+
|4 |null |ABCD | |4 |ABCD |
+-------+------+------+ +-------+------+
|5 |null |BCDE | |5 |BCDE |
+-------+------+------+ +-------+------+
|6 |null |CDEF | |6 |CDEF |
+-------+------+------+ +-------+------+
|7 |JKNN |null | |7 |JKNN |
+-------+------+------+ +-------+------+
|8 |null |DEFG | |8 |DEFG |
+-------+------+------+ +-------+------+
|9 |RRLW |null | |9 |RRLW |
+-------+------+------+ +-------+------+
|10 |GNQN |null | |10 |GNQN |
+-------+------+------+ +-------+------+
|... |? |? | |... |? |
+-------+------+------+ +-------+------+
说明
如上所述,我试图在同一列中合并Person和Company的名称。两个表上的标准JOIN都不起作用,因为它将返回NULL结果。由于LEFT JOIN的性质,可以预期NULL值。这可以通过SQL UNION非常简单地解决,我知道解决方案,但是我正在通过JOIN寻找UNION运算符的替代方案。
无论如何我可以执行JOIN,分组/合并名称列吗?或类似的东西?但是不必使用SQL UNION?
更新
Juan Carlos Oropeza 和 Becuzz 的答案同样可以接受。
答案 0 :(得分:3)
COALESCE听起来会完全按照你的意愿行事。 COALESCE是一个函数,它返回其参数的第一个非NULL值。
SELECT tc."cid",
COALESCE(tp.firstName||' '||tp.lastName, tcp.name) as "name"
FROM "customers" AS tc
LEFT JOIN "person" AS tp
ON tc."cid" = tp."cid"
LEFT JOIN "company" AS tcp
ON tc."cid" = tcp."cid"
答案 1 :(得分:2)
只需添加CASE即可选择使用哪种数据
SELECT tc."cust_id",
CASE WHEN tp."forename" IS NULL
THEN tcp."name"
ELSE CONCAT(tp."forename", ' ', tp."surname")
AS "name"
FROM "tbl_customer" AS tc
LEFT JOIN "tbl_person" AS tp
ON tc."cust_id" = tp."cust_id"
LEFT JOIN "tbl_company" AS tcp
ON tc."cust_id" = tcp."cust_id"