【问题标题】:How to convert JOINs to INs clauses?如何将 JOIN 转换为 IN 子句?
【发布时间】:2020-06-04 04:20:18
【问题描述】:

我关注了 this 链接和其他几个链接,他们展示了如何朝一个特定方向前进,但没有向另一个方向发展。

我用 JOIN 编写的原始查询:

SELECT DISTINCT * FROM membership
JOIN rental ON membership.MEM_NUM = rental.MEM_NUM 
JOIN detailrental ON rental.RENT_NUM = detailrental.RENT_NUM
WHERE DETAIL_DUEDATE < DETAIL_RETURNDATE
GROUP BY membership.MEM_NUM;

我在这里尝试过使用INs:(不起作用)

SELECT DISTINCT * FROM membership
WHERE membership.MEM_NUM IN (SELECT rental.MEM_NUM FROM rental) 
WHERE rental.RENT_NUM IN (SELECT detailrental.RENT_NUM FROM detailrental) 
WHERE DETAIL_DUEDATE < DETAIL_RETURNDATE;

ERD:

我的总体目的是在使用 IN 子句时回答这个问题: 列出延迟归还租借 DVD 的会员的所有详细信息

这是数据库文件: https://pastebin.com/wBjmHcfX

【问题讨论】:

  • 第二个查询中不需要那个 GROUP BY 语句吗?
  • 为什么你特别想把你的JOINs 变成IN 子查询?另请注意,您的原始查询存在缺陷:DISTINCTGROUP BY 不顺利,SELECT *GROUP BY 也是如此。您可能应该尝试对您的总体目的进行更详细的解释。
  • DISTINCT * 是一个完全没有意义的结构——自相矛盾或同义反复,取决于你的观点
  • 我向你学习了很多,以后一定会避免这样的错误。

标签: mysql


【解决方案1】:

我不知道你为什么要这样做。

因为我认为这不会更快。

我还添加了 GROUP By 子句。

SELECT DISTINCT * FROM membership
WHERE membership.MEM_NUM IN (SELECT rental.MEM_NUM 
                             FROM rental 
                             WHERE rental.RENT_NUM IN (SELECT detailrental.RENT_NUM 
                                                       FROM detailrental 
                                                       WHERE DETAIL_DUEDATE < DETAIL_RETURNDATE)
                            ) 
GROUP BY membership.MEM_NUM;

基于您的数据的示例

CREATE TABLE `price` (
  `PRICE_CODE` decimal(2,0) NOT NULL,
  `PRICE_DESCRIPTION` varchar(20) NOT NULL,
  `PRICE_RENTFEE` decimal(5,2) DEFAULT NULL,
  `PRICE_DAILYLATEFEE` decimal(5,2) DEFAULT NULL,
  PRIMARY KEY (`PRICE_CODE`)
);
CREATE TABLE `movie` (
  `MOVIE_NUM` decimal(8,0) NOT NULL,
  `MOVIE_TITLE` varchar(75) NOT NULL,
  `MOVIE_YEAR` decimal(4,0) DEFAULT NULL,
  `MOVIE_COST` decimal(5,2) DEFAULT NULL,
  `MOVIE_GENRE` varchar(50) DEFAULT NULL,
  `PRICE_CODE` decimal(2,0) DEFAULT NULL,
  PRIMARY KEY (`MOVIE_NUM`),
  KEY `PRICE_CODE` (`PRICE_CODE`),
  CONSTRAINT `movie_ibfk_1` FOREIGN KEY (`PRICE_CODE`) REFERENCES `price` (`PRICE_CODE`)
);
CREATE TABLE `video` (
  `VID_NUM` decimal(8,0) NOT NULL,
  `VID_INDATE` date DEFAULT NULL,
  `MOVIE_NUM` decimal(8,0) DEFAULT NULL,
  PRIMARY KEY (`VID_NUM`),
  KEY `MOVIE_NUM` (`MOVIE_NUM`),
  CONSTRAINT `video_ibfk_1` FOREIGN KEY (`MOVIE_NUM`) REFERENCES `movie` (`MOVIE_NUM`)
);
CREATE TABLE `membership` (
  `MEM_NUM` decimal(8,0) NOT NULL,
  `MEM_FNAME` varchar(30) NOT NULL,
  `MEM_LNAME` varchar(30) NOT NULL,
  `MEM_STREET` varchar(120) DEFAULT NULL,
  `MEM_CITY` varchar(50) DEFAULT NULL,
  `MEM_STATE` char(2) DEFAULT NULL,
  `MEM_ZIP` char(5) DEFAULT NULL,
  `MEM_BALANCE` decimal(10,2) DEFAULT NULL,
  PRIMARY KEY (`MEM_NUM`)
);
CREATE TABLE `rental` (
  `RENT_NUM` decimal(8,0) NOT NULL,
  `RENT_DATE` date DEFAULT NULL,
  `MEM_NUM` decimal(8,0) DEFAULT NULL,
  PRIMARY KEY (`RENT_NUM`),
  KEY `MEM_NUM` (`MEM_NUM`),
  CONSTRAINT `rental_ibfk_1` FOREIGN KEY (`MEM_NUM`) REFERENCES `membership` (`MEM_NUM`)
);
CREATE TABLE `detailrental` (
  `RENT_NUM` decimal(8,0) NOT NULL,
  `VID_NUM` decimal(8,0) NOT NULL,
  `DETAIL_FEE` decimal(5,2) DEFAULT NULL,
  `DETAIL_DUEDATE` date DEFAULT NULL,
  `DETAIL_RETURNDATE` date DEFAULT NULL,
  `DETAIL_DAILYLATEFEE` decimal(5,2) DEFAULT NULL,
  PRIMARY KEY (`RENT_NUM`,`VID_NUM`),
  KEY `VID_NUM` (`VID_NUM`),
  CONSTRAINT `detailrental_ibfk_1` FOREIGN KEY (`RENT_NUM`) REFERENCES `rental` (`RENT_NUM`),
  CONSTRAINT `detailrental_ibfk_2` FOREIGN KEY (`VID_NUM`) REFERENCES `video` (`VID_NUM`)
);
INSERT INTO `membership` VALUES (102,'TAMI','DAWSON','2632 TAKLI CIRCLE','NORENE','TN','37136',11.00),(103,'CURT','KNIGHT','4025 CORNELL COURT','FLATGAP','KY','41219',6.00),(104,'JAMAL','MELENDEZ','788 EAST 145TH AVENUE','QUEBECK','TN','38579',0.00),(105,'IVA','MCCLAIN','6045 MUSKET BALL CIRCLE','SUMMIT','KY','42783',15.00),(106,'MIRANDA','PARKS','4469 MAXWELL PLACE','GERMANTOWN','TN','38183',0.00),(107,'ROSARIO','ELLIOTT','7578 DANNER AVENUE','COLUMBIA','TN','38402',5.00),(108,'MATTIE','GUY','4390 EVERGREEN STREET','LILY','KY','40740',0.00),(109,'CLINT','OCHOA','1711 ELM STREET','GREENEVILLE','TN','37745',10.00),(110,'LEWIS','ROSALES','4524 SOUTHWIND CIRCLE','COUNCE','TN','38326',0.00),(111,'STACY','MANN','2789 EAST COOK AVENUE','MURFREESBORO','TN','37132',8.00),(112,'LUIS','TRUJILLO','7267 MELVIN AVENUE','HEISKELL','TN','37754',3.00),(113,'MINNIE','GONZALES','6430 VASILI DRIVE','WILLISTON','TN','38076',0.00);
INSERT INTO `price` VALUES (1,'Standard',3.00,1.00),(2,'New Release',4.50,3.00),(3,'Discount',2.50,1.00),(4,'Weekly Special',2.00,0.50);
INSERT INTO `movie` VALUES (1234,'The Cesar Family Christmas',2014,39.95,'FAMILY',2),(1235,'Smokey Mountain Wildlife',2011,59.95,'ACTION',3),(1236,'Richard Goodhope',2015,59.95,'DRAMA',2),(1237,'Beatnik Fever',2014,29.95,'COMEDY',2),(1238,'Constant Companion',2015,89.95,'DRAMA',NULL),(1239,'Where Hope Dies',2005,25.49,'DRAMA',3),(1245,'Time to Burn',2015,45.49,'ACTION',3),(1246,'What He Doesn\'t Know',2013,58.29,'COMEDY',1);
INSERT INTO `video` VALUES (34341,'2014-01-22',1235),(34342,'2014-01-22',1235),(34366,'2016-03-02',1236),(34367,'2016-03-02',1236),(34368,'2016-03-02',1236),(34369,'2016-03-02',1236),(44392,'2015-10-21',1237),(44397,'2015-10-21',1237),(54321,'2015-06-18',1234),(54324,'2015-06-18',1234),(54325,'2015-06-18',1234),(59237,'2016-02-14',1237),(61353,'2013-01-28',1245),(61354,'2013-01-28',1245),(61367,'2015-07-30',1246),(61369,'2015-07-30',1246),(61388,'2014-01-25',1239);
INSERT INTO `rental` VALUES (1001,'2016-03-01',103),(1002,'2016-03-01',105),(1003,'2016-03-02',102),(1004,'2016-03-02',110),(1005,'2016-03-02',111),(1006,'2016-03-02',107),(1007,'2016-03-02',104),(1008,'2016-03-03',105),(1009,'2016-03-03',111);
INSERT INTO `detailrental` VALUES (1001,34342,2.00,'2016-03-04','2016-03-02',NULL),(1001,34366,3.50,'2016-03-04','2016-03-02',3.00),(1001,61353,2.00,'2016-03-04','2016-03-03',1.00),(1002,59237,3.50,'2016-03-04','2016-03-04',3.00),(1003,54325,3.50,'2016-03-04','2016-03-09',3.00),(1003,61369,2.00,'2016-03-06','2016-03-09',1.00),(1003,61388,0.00,'2016-03-06','2016-03-09',1.00),(1004,34341,2.00,'2016-03-07','2016-03-07',1.00),(1004,34367,3.50,'2016-03-05','2016-03-07',3.00),(1004,44392,3.50,'2016-03-05','2016-03-07',3.00),(1005,34342,2.00,'2016-03-07','2016-03-05',1.00),(1005,44397,3.50,'2016-03-05','2016-03-05',3.00),(1006,34366,3.50,'2016-03-05','2016-03-04',3.00),(1006,61367,2.00,'2016-03-07',NULL,1.00),(1007,34368,3.50,'2016-03-05',NULL,3.00),(1008,34369,3.50,'2016-03-05','2016-03-05',3.00),(1009,54324,3.50,'2016-03-05',NULL,3.00);
✓ ✓ ✓ ✓ ✓ ✓
SELECT DISTINCT * FROM membership
WHERE membership.MEM_NUM IN (SELECT rental.MEM_NUM 
                             FROM rental 
                             WHERE rental.RENT_NUM IN (SELECT detailrental.RENT_NUM 
                                                       FROM detailrental 
                                                       WHERE DETAIL_DUEDATE < DETAIL_RETURNDATE)
                            ) 
GROUP BY membership.MEM_NUM;
MEM_NUM | MEM_FNAME | MEM_LNAME |记忆街道 |记忆城市 |记忆状态 | MEM_ZIP |内存余额 ------: | :-------- | :-------- | :-------------------- | :------- | :-------- | :-------- | ----------: 102 |塔米 |道森 |第2632章诺琳 |田纳西州 | 37136 | 11.00 110 |刘易斯 |罗萨莱斯 | 4524 南风圈 |会议 |田纳西州 | 38326 | 0.00

db小提琴here

【讨论】:

  • 您输入的以下查询给我一个错误Error Code: 1054. Unknown column 'DETAIL_DUEDATE' in 'where clause'
  • 我试过这个并没有解决问题AND detailrental.DETAIL_DUEDATE &lt; detailrental.DETAIL_RETURNDATE
  • 我编辑了我的帖子以添加数据库文件,以防您想测试您的查询。谢谢!
  • AND 子句应该与您的第三个选择一起使用,否则它将不起作用
猜你喜欢
  • 2023-03-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-30
  • 1970-01-01
  • 2015-04-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多