应该使用哪个SQL子句?

时间:2014-02-11 13:34:26

标签: sql firebird clause

我在Firebird中有这样的表:

Tablename: USERNAMES


+--------+-----+
|username|code |
+--------+-----+
|a       |1    |
+--------+-----+
|b       |2    |
+--------+-----+
|c       |3    |
+--------+-----+
|d       |4    |
+--------+-----+
|e       |5    |
+--------+-----+

和这张表

Tablename: SERVICES
+-----------+-----+-----+-----+
|serviceno  |user1|user2|user3|
+-----------+-----+-----+-----+
|v1         |     |1    |2    |
+-----------+-----+-----+-----+
|v2         |3    |2    |     |
+-----------+-----+-----+-----+
|v3         |5    |4    |     |
+-----------+-----+-----+-----+
|v4         |3    |2    |1    |
+-----------+-----+-----+-----+

我希望该表格为

    +-----------+-----+-----+-----+
    |serviceno  |user1|user2|user3|
    +-----------+-----+-----+-----+
    |v1         |     |a    |b    |
    +-----------+-----+-----+-----+
    |v2         |c    |b    |     |
    +-----------+-----+-----+-----+
    |v3         |e    |d    |     |
    +-----------+-----+-----+-----+
    |v4         |c    |b    |a    |
    +-----------+-----+-----+-----+

我试过了

 SELECT IFF(A.USER1 = NULL,NULL,B.NAME),
    IFF(A.USER2 = NULL,NULL,C.NAME),
    IFF(A.USER3 = NULL,NULL,D.NAME)
     FROM SERVICES A INNER JOIN USERNAMES B ON (A.USER1 =B.CODE)
    INNER JOIN USERNAMES C ON (A.USER2 =C.CODE)
    INNER JOIN USERNAMES D ON (A.USER3 =D.CODE)

还有几次尝试,但总的来说结果只是第v4行。为什么?我怎样才能获得所有行?

3 个答案:

答案 0 :(得分:4)

您应该使用OUTER JOINS

SELECT serviceno,
       IFF(A.USER1 = NULL,NULL,B.NAME),
       IFF(A.USER2 = NULL,NULL,C.NAME),
       IFF(A.USER3 = NULL,NULL,D.NAME)
 FROM SERVICES A
      LEFT OUTER JOIN USERNAMES B ON (A.USER1 =B.CODE)
      LEFT OUTER JOIN USERNAMES C ON (A.USER2 =C.CODE)
      LEFT OUTER JOIN USERNAMES D ON (A.USER3 =D.CODE)

内部联接仅在匹配时返回结果,即使user1user2user3为空,您想要的结果也需要行,因此e之间没有匹配。 G。 AB

您可以将其简化为

SELECT serviceno,
       B.NAME,
       C.NAME,
       D.NAME
 FROM SERVICES A
      LEFT OUTER JOIN USERNAMES B ON (A.USER1 =B.CODE)
      LEFT OUTER JOIN USERNAMES C ON (A.USER2 =C.CODE)
      LEFT OUTER JOIN USERNAMES D ON (A.USER3 =D.CODE)

答案 1 :(得分:3)

SELECT serviceno, u1.username as user1, u2.username as user2, u3.username as user3  FROM Services 
LEFT OUTER JOIN USERNAMES u1 ON user1 = u1.code 
LEFT OUTER JOIN USERNAMES u2 ON user2 = u2.code
LEFT OUTER JOIN USERNAMES u3 ON user3 = u3.code

答案 2 :(得分:-1)

我不熟悉Firebird,但这是一个通用的SQL解决方案:

select
    serviceno,
    (select username
       from usernames
      where services.user1 = usernames.code) as user1,
    (select username
       from usernames
      where services.user2 = usernames.code) as user2,
    (select username
       from usernames
      where services.user3 = usernames.code) as user3
from
    services