2017-11-25 161 views
3

我有以下表和数据:SQL查询在同一个表JOIN给定数据

CREATE TABLE TEST_TABLE (
    ID NUMBER(6) NOT NULL, 
    COMMON_SEQ NUMBER(22), 
    NAME VARCHAR(20), 
    CONSTRAINT PK_CONST PRIMARY KEY (ID) 
); 
INSERT INTO TEST_TABLE (ID, COMMON_SEQ, NAME) VALUES (1001, NULL, 'Michelle'); 
INSERT INTO TEST_TABLE (ID, COMMON_SEQ, NAME) VALUES (1002, NULL, 'Tiberius'); 
INSERT INTO TEST_TABLE (ID, COMMON_SEQ, NAME) VALUES (1003, NULL, 'Marigold'); 
INSERT INTO TEST_TABLE (ID, COMMON_SEQ, NAME) VALUES (1004, 999, 'Richmond'); 
INSERT INTO TEST_TABLE (ID, COMMON_SEQ, NAME) VALUES (1005, 999, 'Marianne'); 
INSERT INTO TEST_TABLE (ID, COMMON_SEQ, NAME) VALUES (1006, NULL, 'Valentin'); 
INSERT INTO TEST_TABLE (ID, COMMON_SEQ, NAME) VALUES (1007, 888, 'Juliette'); 
INSERT INTO TEST_TABLE (ID, COMMON_SEQ, NAME) VALUES (1008, NULL, 'Lawrence'); 

在此表中的一些记录被COMMON_SEQ的共同价值(与对方的例子COMMON_SEQ 999涉及里士满和玛丽安)。

如何根据给定ID作为输入选择所有名称?

我试着将表加入自己(当COMMON_SEQ为空时工作正常)。此示例返回米歇尔记录:

SELECT T.ID, T.COMMON_SEQ,T.NAME 
FROM TEST_TABLE T 
LEFT JOIN TEST_TABLE T2 ON NOT T.COMMON_SEQ is NULL 
    AND T.COMMON_SEQ=T2.COMMON_SEQ AND T.ID<>T2.ID 
WHERE T.ID=1001 

不过,这并不带回2个记录ID 1004这个例子只返回里士满记录(但我还需要返回玛丽安记录):

SELECT T.ID, T.COMMON_SEQ,T.NAME 
FROM TEST_TABLE T 
LEFT JOIN TEST_TABLE T2 ON NOT T.COMMON_SEQ is NULL 
    AND T.COMMON_SEQ=T2.COMMON_SEQ AND T.ID<>T2.ID 
WHERE T.ID=1004 

当我只提供一个ID值(1004或1005)时,如何改进/重写查询以返回Richmond和Marianne记录?

+0

因为NULL = NULL是不正确的。 (你可以使用'x不是从y'离开,如果可用的话) – wildplasser

+0

你使用哪个数据库?甲骨文? – Ramesh

+0

@Ramesh我使用2个数据库:H2和Oracle。我需要适用于这两者的通用SQL。 – user1697575

回答

4

你可以使用:

SELECT * 
FROM TEST_TABLE t 
WHERE COMMON_SEQ IN (SELECT COMMON_SEQ 
        FROM TEST_TABLE t1 
        WHERE t1.ID = 1004) 
    OR t.ID = 1004;     

DBFiddle Demo

传递相同的参数两次COMMON_SEQ处理NULL

+1

谢谢!我只是试过了,它会为我的所有测试用例返回预期的结果! – user1697575

+0

@ user1697575很高兴听到它。 – lad2025

2

试试这个

SELECT COALESCE (ty.id, tx.id) AS id, 
     COALESCE (ty.common_seq, tx.common_seq) AS common_seq, 
     COALESCE (ty.name, tx.name) AS name 
    FROM test_table tx LEFT OUTER JOIN test_table ty 
      ON (tx.common_seq = ty.common_seq) 
WHERE tx.ID = 1004; 

有了这个,你能避免使用IN或EXISTS,这很可能是更好的性能。

+0

谢谢!有用。 – user1697575

+0

@ user1697575 - 很高兴帮助 – Ramesh

+0

只是好奇你为什么使用COALESCE函数?我不能只使用SELECT ty。* FROM ...? – user1697575