我想了解以下几个查询之间的区别

问题描述 投票:0回答:1

我有一个销售人员和一个客户表,我试图找到所有的销售人员,谁住在任何一个城市的客户居住(注意,客户是关联到一个特定的销售人员,但现在我们只是比较的城市)。

CREATING TABLE (ORACLE)

CREATE TABLE SALESMAN (  
    SALESMAN_ID INT CONSTRAINT SALESMAN_PK PRIMARY KEY,  
    NAME VARCHAR2(15),  
    CITY VARCHAR2(10),  
    COMMISSION DECIMAL(4,2))
;

INSERT ALL  
    INTO SALESMAN VALUES(5001,'JAMES HOOG','NEW YORK',0.15)  
    INTO SALESMAN VALUES(5002,'NAIL KNITE','PARIS',0.13)  
    INTO SALESMAN VALUES(5005,'PIT ALEX','LONDON',0.11)  
    INTO SALESMAN VALUES(5006,'MC LYON','PARIS',0.14)  
    INTO SALESMAN VALUES(5003,'LAUSON HEN','SAN JOSE',0.12)  
    INTO SALESMAN VALUES(5007,'PAUL ADAM','ROME',0.13)  
SELECT * FROM DUAL
;

CREATE TABLE CUSTOMER (   
    CUSTOMER_ID INT CONSTRAINT CUSTOMER_PK PRIMARY KEY,   
    CUST_NAME VARCHAR2(15),   
    CITY VARCHAR(10),   
    GRADE INT,   
    SALESMAN_ID INT,  
    CONSTRAINT FK_CUSTOMER_SALESMAN  
    FOREIGN KEY (SALESMAN_ID) REFERENCES SALESMAN (SALESMAN_ID)) 
;

INSERT ALL   
    INTO CUSTOMER VALUES (3002, 'NICK RIMANDO', 'NEW YORK', 100, 5001)   
    INTO CUSTOMER VALUES (3007, 'BRAD DAVIS', 'NEW YORK', 200, 5001)   
    INTO CUSTOMER VALUES (3005, 'GRAHAM ZUSI', 'CALIFORNIA', 200,5002)   
    INTO CUSTOMER VALUES (3008, 'JULIAN GREEN', 'LONDON', 300,5002)   
    INTO CUSTOMER VALUES (3004, 'FABIAN JOHSON', 'PARIS',300,5006)   
    INTO CUSTOMER VALUES (3009, 'GEOFF CAMEROON', 'BERLIN', 100,5003)   
    INTO CUSTOMER VALUES (3003, 'JOZY ALTIDOR', 'MOSCOW', 200,5007)   
    INTO CUSTOMER VALUES (3001, 'BRAD GUZAN', 'LONDON',NULL,5005)   
SELECT * FROM DUAL
;

SELECT * FROM SALESMAN;

SALESMAN_ID       NAME  CITY    COMMISSION
5001         JAMES HOOG NEW YORK    .15
5002         NAIL KNITE PARIS       .13
5005          PIT ALEX  LONDON      .11
5006          MC LYON   PARIS       .14
5003        LAUSON HEN  SAN JOSE    .12
5007          PAUL ADAM ROME        .13

SELECT * FROM CUSTOMER;

CUSTOMER_ID       CUST_NAME      CITY      GRADE    SALESMAN_ID
3002            NICK RIMANDO    NEW YORK    100       5001
3007             BRAD DAVIS     NEW YORK    200       5001
3005             GRAHAM ZUSI    CALIFORNIA  200       5002
3008            JULIAN GREEN    LONDON      300       5002
3004           FABIAN JOHSON    PARIS       300       5006
3009           GEOFF CAMEROON   BERLIN      100       5003
3003            JOZY ALTIDOR    MOSCOW      200       5007
3001            BRAD GUZAN      LONDON       -        5005

# EXPECTED OUTPUT
SALESMAN_ID    NAME     CITY      COMMISSION
5001        JAMES HOOG  NEW YORK    .15
5006         MC LYON    PARIS       .14
5005        PIT ALEX    LONDON      .11
5002       NAIL KNITE    PARIS      .13

# QUERY 1

SELECT DISTINCT
SLS.*
FROM SALESMAN SLS, CUSTOMER CUST
WHERE SLS.CITY = CUST.CITY

# QUERY 2
SELECT * FROM SALESMAN SLS  
WHERE EXISTS (SELECT SALESMAN_ID FROM CUSTOMER WHERE SLS.CITY = CUSTOMER.CITY)

# QUERY 3
SELECT * FROM SALESMAN SLS  
WHERE SLS.SALESMAN_ID IN  (SELECT DISTINCT CUST.SALESMAN_ID FROM CUSTOMER CUST WHERE SLS.CITY = CUST.CITY)
;

# OUTPUT FROM QUERY 3
SALESMAN_ID      NAME       CITY    COMMISSION
5001         JAMES HOOG   NEW YORK  .15
5006        MC LYON        PARIS    .14
5005        PIT ALEX      LONDON    .11

在上面的三个查询中,查询1和2给出了预期的输出,但是查询3没有提供预期的输出。所有的查询都有相同的连接城市从销售人员和客户表,但我不明白为什么查询3给出了一个不同的输出。

sql oracle join subquery aggregate
1个回答
0
投票

更新

根据评论,第三个查询的正确形式应该只是检查客户表中是否存在任何销售员的城市。

SELECT * FROM SALESMAN SLS  
WHERE SLS.CITY IN  (SELECT DISTINCT CITY FROM CUSTOMER CUST)

这和前两个查询的结果是一样的.

在dbfiddle上演示

原答案

你的第三个查询给出不同的结果的原因是子查询 只是 返回存在于 customer 每一个城市都是如此。salesman在这种情况下,它们是5001、5005和5006。所以你在输出中没有得到NAIL KNITE,因为在PARIS、LONDON或NEW YORK的客户都没有NAIL这个销售员。

请注意,可以说查询3实际上返回的是正确的结果,因为你的其他查询并没有考虑某个销售员在任何给定城市是否有客户。所以你的另外两个查询其实应该是。

查询一:

SELECT DISTINCT
SLS.*
FROM SALESMAN SLS
JOIN CUSTOMER CUST ON SLS.CITY = CUST.CITY AND SLS.SALESMAN_ID = CUST.SALESMAN_ID
ORDER BY SLS.SALESMAN_ID

查询2

SELECT * FROM SALESMAN SLS  
WHERE EXISTS (SELECT * FROM CUSTOMER WHERE SLS.CITY = CUSTOMER.CITY AND CUSTOMER.SALESMAN_ID = SLS.SALESMAN_ID)
ORDER BY SALESMAN_ID

有了这些改变,所有三个查询的结果都是一样的。

SALESMAN_ID     NAME        CITY        COMMISSION
5001            JAMES HOOG  NEW YORK    .15
5005            PIT ALEX    LONDON      .11
5006            MC LYON     PARIS       .14

在dbfiddle上演示


0
投票

在第三个查询中,你缺少了 join 而你期望的工作与你的第二个查询相同。下面是你的第三个查询 join.

SELECT * FROM SALESMAN SLS  
WHERE SLS.SALESMAN_ID 
IN  (
      SELECT 
        DISTINCT CUST.SALESMAN_ID 
      FROM CUSTOMER CUST 
      JOIN SALESMAN_ID SLS
      ON SLS.CITY = CUST.CITY
    )

EXISTS 当子查询的结果非常大时,比IN快得多,而 IN 远远快于 EXISTS 当子查询结果很小的时候。

© www.soinside.com 2019 - 2024. All rights reserved.