带有3个select语句的SQL语句

时间:2017-05-11 20:26:27

标签: sql oracle

我正在尝试将三个表的数据合并,但遇到了一个小问题。

假设我们有3张桌子

表A

ID | ID2 | ID3 | Name | Age
 1    2x    4y   John    23
 2    7j         Mike    27
 3    1S1   6HH  Steve   67
 4    45    O8   Carol   56

表B

 | ID2 | ID3  | Price
    2x    4y      23
    7j    8uj     27
    x4    Q6      56

表C

|ID | Weight|
  1    145
  1    210
  1    240
  2    234
  2    110
  3    260
  3    210
  4    82

我希望从表A中获得每个重量为200或更多但是不能在表B中的记录。表A和C通过ID连接。表A和表B由ID2或ID3连接。 ID2和ID3都不一定必须填充,但至少会有1个。要么存在,要么两者兼而有之,它们将是独一无二的。所以期望的结果是

3 | 1S1 | 6HH | Steve| 67

请注意,一个人可以拥有多个权重,但只要至少有一个记录是200或更高,就会被拉扯。

到目前为止我有什么

Select *
From tableA x 
Where 
    x.id in (Select distinct y.id
             From tableA y, tableC z
             Where y.id = z.id 
               And z.weight >= '200' 
               And y.id not in (Select distinct h.id
                                From tableA h, tableB k
                                Where (h.id2 = k.id2 or h.id3 = k.id3)))

当我这样做时,似乎忽略了对tableB的检查,我得到了John,Mike和Steve。有任何想法吗?对不起,这是令人费解的,这是我必须要合作的。顺便说一句,我是在oracle中这样做的。

4 个答案:

答案 0 :(得分:3)

这听起来像existsnot exists。所以直接翻译是:

select a.*
from tableA a
where exists (select 1 from tableC c where c.id = a.id and c.weight >= 200) and
      not exists (select 1 from tableB b where b.id2 = a.id2 or b.id3 = a.id3);

or拆分为两个独立的子查询通常可以提高性能:

select a.*
from tableA a
where exists (select 1 from tableC c where c.id = a.id and c.weight >= 200) and
      not exists (select 1 from tableB b where b.id2 = a.id2) and
      not exists (select 1 from tableB b where b.id3 = a.id3);

答案 1 :(得分:1)

这就是我想出来的。

SELECT DISTINCT
  A.ID,
  A.ID2,
  A.ID3,
  A.Name,
  A.Age
FROM 
                  A
  LEFT OUTER JOIN C ON C.ID = A.ID
  LEFT OUTER JOIN B ON 
       B.ID2 = A.ID2 
   OR  B.ID3 = A.ID3    
WHERE
      C.Weight >= 200
   AND B.Price IS NULL

以下是测试数据

CREATE TABLE A
(
  ID INT,
  ID2 VARCHAR(3),
  ID3 VARCHAR(3),
  Name VARCHAR(10),
  Age INT
);

INSERT INTO A VALUES (1, '2x', '4y', 'John', 23);
INSERT INTO A VALUES (2, '7j', NULL , 'Mike', 27);
INSERT INTO A VALUES (3, '1S1', '6HH', 'Steve', 67);
INSERT INTO A VALUES (4, '45', 'O8', 'Carol', 56);

CREATE TABLE B
(
  ID2 VARCHAR(3),
  ID3 VARCHAR(3),
  Price INT
 );

 INSERT INTO B VALUES ('2x', '4y', 23);
 INSERT INTO B VALUES ('7j', '8uj', 27);
 INSERT INTO B VALUES ('x4', 'Q6', 56);

 CREATE TABLE C
 (
   ID INT,
   Weight INT
 );

 INSERT INTO C VALUES (1, 145);
 INSERT INTO C VALUES (1, 210);
 INSERT INTO C VALUES (1, 240);
 INSERT INTO C VALUES (2, 234);
 INSERT INTO C VALUES (2, 110);
 INSERT INTO C VALUES (3, 260);
 INSERT INTO C VALUES (3, 210);
 INSERT INTO C VALUES (4, 82);

答案 2 :(得分:0)

Select a.id, a.id2, a.id3
From table_a a
Left join table_c c on a.id = c.id
Where c.weight >=200
      And not exists
      (Select 1
         From table_b b
       Where a.id = b.id2
              Or a.id = b.id3
       );

答案 3 :(得分:0)

我在敲答答案,但我在表a和c上使用了INNER JOIN,在表b上使用了NOT EXISTS

--This first section is creating the test data
with Table_A (id, id2, id3, Name, age) as
    (select 1,    '2x',    '4y',   'John',    23 from dual union all
    select 2,    '7j',    null,     'Mike',    27 from dual union all
    select 3,    '1S1',   '6HH',  'Steve',  67 from dual union all
    select 4,    '45',    'O8',   'Carol',   56 from dual),
Table_B(id2, id3, price) as
    (select    '2x',    '4y',      23 from dual union all
    select    '7j',    '8uj',     27 from dual union all
    select    'x4',    'Q6',      56 from dual),
Table_C(id, weight) as
    (select  1,    145 from dual union all
    select  1,    210 from dual union all
    select  1,    240 from dual union all
    select  2,    234 from dual union all
    select  2,    110 from dual union all
    select  3,    260 from dual union all
    select  3,    210 from dual union all
    select  4,    82 from dual)
--Actual query starts here
select distinct a.*
from   table_a a
  --join to table c, include the weight filter
  inner join table_c c on (a.id = c.id and c.weight >= 200)    
where not exists  -- The rest is the NOT EXISTS to exclude the values in table b
  (select 1 from table_b b
   where a.id2 = b.id2
      or a.id3 = b.id3);