我有一个销售人员和一个客户表,我试图找到所有的销售人员,谁住在任何一个城市的客户居住(注意,客户是关联到一个特定的销售人员,但现在我们只是比较的城市)。
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给出了一个不同的输出。
更新
根据评论,第三个查询的正确形式应该只是检查客户表中是否存在任何销售员的城市。
SELECT * FROM SALESMAN SLS
WHERE SLS.CITY IN (SELECT DISTINCT CITY FROM CUSTOMER CUST)
这和前两个查询的结果是一样的.
原答案
你的第三个查询给出不同的结果的原因是子查询 只是 返回存在于 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
在第三个查询中,你缺少了 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
当子查询结果很小的时候。