如何只从一个表中减去另一个表中的行一次

时间:2012-03-24 02:31:13

标签: sql oracle subtraction

我正在为一个大学项目工作,我有以下问题: 我在Oracle DB中有2个表...我需要从table1中选择那些不包含在table2中的行...但主要的问题是我需要从table2中排除那些被选中的行...例如:

Table1                       Table2                      ResultTable
id  | Number | Letter        id  | Number | Letter       id  | Number | Letter
_____________________        _____________________       _____________________
1        4        S          1       6        G          2        2        P 
2        2        P          2       8        B          3        5        B
3        5        B          3       4        S          4        4        S
4        4        S          4       1        A          6        2        P
5        1        A          5       1        H
6        2        P          6       2        X

那么,你怎么看,如果表1中的一行在表2中有一个“双胞胎”,它们都被排除在外。

4 个答案:

答案 0 :(得分:1)

将其分成几部分。

也许你有一个EOR - 独家OR。

所以你可能有 (condition1
OR
condition2)
AND NOT
(condition1 AND condition2)

答案 1 :(得分:1)

可能最彻底的查询是:

SELECT table1.id,
       table1.digit,
       table1.letter
  FROM ( SELECT id,
                digit,
                letter,
                ROW_NUMBER() OVER (PARTITION BY digit, letter ORDER BY id) rn
           FROM table1
       ) table1
  LEFT
  JOIN ( SELECT id,
                digit,
                letter,
                ROW_NUMBER() OVER (PARTITION BY digit, letter ORDER BY id) rn
           FROM table2
       ) table2
    ON table2.digit = table1.digit
   AND table2.letter = table1.letter
   AND table2.rn = table1.rn
 WHERE table2.id IS NULL
 ORDER
    BY table1.id
;

分别为table1table2 a"行号"在"双胞胎"中。例如,这个:

SELECT id,
       digit,
       letter,
       ROW_NUMBER() OVER (PARTITION BY digit, letter ORDER BY id) rn
  FROM table1
 ORDER
    BY table1.id
;

返回:

        ID      DIGIT LETT         RN
---------- ---------- ---- ----------
         1          4 S             1
         2          2 P             1
         3          5 B             1
         4          4 S             2     -- second row with 4 S
         5          1 A             1
         6          2 P             2     -- second row with 2 P

也就是说,如果您知道在(digit, letter)中不会出现table2次,那么您可以使用EXISTS代替ROW_NUMBER()来大大简化这一过程:< / p>

SELECT id,
       digit,
       letter
  FROM table1 table1a
 WHERE EXISTS
        ( SELECT 1
            FROM table1
           WHERE digit = table1a.digit
             AND letter = table1a.letter
             AND id < table1a.id
        )
    OR NOT EXISTS
        ( SELECT 1
            FROM table2
           WHERE digit = table1a.digit
             AND letter = table1a.letter
        )
;

答案 2 :(得分:0)

使用Oracle MINUS关键字,它完全符合您的要求。有关详细信息,请参阅http://oreilly.com/catalog/mastorasql/chapter/ch07.html

答案 3 :(得分:-1)

我无法看到如何使用一个SQL SELECT执行您想要的操作。

我认为你需要一个临时表和几个陈述。

使用tmpResultsid1称呼id2,其匹配来自id的{​​{1}}和来自Table1的{​​{1}}分别。

id
相关问题