双层 not exist 嵌套

本文介绍了一种SQL查询技巧,用于找出选读了全部课程的学生姓名。通过逐步分解查询语句,从查找未选课程到最终确定完成所有课程学习的学生。

STUDENT:

CREATE TABLE `student` (
  `STUID` varchar(40) DEFAULT NULL,
  `STUNAME` varchar(100) DEFAULT NULL,
)

COURSE:

CREATE TABLE `course` (
  `COURSEID` varchar(40) DEFAULT NULL,
  `COURSENAME` varchar(100) DEFAULT NULL
) 
REGISTER:

CREATE TABLE `register` (
  `STUID` varchar(40) DEFAULT NULL,
  `COURSEID` varchar(40) DEFAULT NULL,
  `GRADE` smallint(6) DEFAULT NULL
)

问题:检索选读全部课程的学生姓名
SELECT STUNAME FROM STUDENT
	WHERE NOT EXISTS (
		SELECT * FROM COURSE WHERE NOT EXISTS (
			SELECT * FROM register WHERE register.COURSEID = COURSE.COURSEID AND  register.STUID =STUDENT.STUID)
	)
现在我们从后面的子查询向前分解:

1.所有未选过的课程的数据集:

SELECT * FROM COURSE WHERE NOT EXISTS (
	SELECT * FROM register WHERE COURSEID = COURSE.COURSEID)


2.所有没被某位学号为 @STUID 的学生选过的课程的记录集(@STUID学生的未选课程):
SELECT * FROM COURSE WHERE NOT EXISTS (
	SELECT * FROM register WHERE register.COURSEID = COURSE.COURSEID AND  STUID =@STUID)

3.遍历每一个主查询的学号,每一个学号都按第二筛选方法筛选出:没有未选课程的学生的学号。(不包括在第查询方法查询出的“有未学课程的学号的记录集”中的记录。)
请注意:用主查询中的 学生.学号 代替了@STUID。
SELECT STUNAME FROM STUDENT
	WHERE NOT EXISTS (
		SELECT * FROM COURSE WHERE NOT EXISTS (
			SELECT * FROM register WHERE register.COURSEID = COURSE.COURSEID AND  register.STUID =STUDENT.STUID)
	)

这已经是整个查询语句,可以看出子查询中用学生.学号替换了第2步中的 @STUID,(没忘了吧,第二步求的是没有选修全部课程的某个学生)。


From: http://blog.youkuaiyun.com/mtawaken/article/details/6573122

@echo off chcp 65001 > nul setlocal enabledelayedexpansion cd /d "%~dp0" :: === 计数机制 === set "COUNT_FILE=monitor_count.dat" if not exist "%COUNT_FILE%" (echo 0 > "%COUNT_FILE%") set /p TOTAL_COUNT=<"%COUNT_FILE%" :: === 主循环持续检测 === :monitor_loop cls echo ===== DEVICE PARTITION MONITOR ===== echo [%TIME%] Waiting for device connection... echo Total Checks: !TOTAL_COUNT! echo Press Ctrl+C to stop monitoring echo =================================== :: 等待设备连接 :wait_for_device adb devices | findstr /r /c:"device$" >nul if !errorlevel! neq 0 ( timeout /t 5 >nul goto :wait_for_device ) :: 等待设备启动完成 :wait_for_boot adb shell "getprop sys.boot_completed" 2>nul > boot_status.txt if exist boot_status.txt ( set /p BOOT_STATUS=<boot_status.txt del boot_status.txt if "!BOOT_STATUS!" neq "1" ( echo [%TIME%] Waiting for device to boot... timeout /t 5 >nul goto :wait_for_boot ) ) else ( timeout /t 5 >nul goto :wait_for_boot ) :: === 执行分区检测 === set /a TOTAL_COUNT+=1 echo !TOTAL_COUNT! > "%COUNT_FILE%" :: 日志配置 set "LOG_PREFIX=Partition_Log" set "TIMESTAMP=%date:~0,4%-%date:~5,2%-%date:~8,2%" set "LOG_FILE=%LOG_PREFIX%_%TIMESTAMP%.log" :: 预期文件检查 set "EXPECTED_FILE=expected_result.txt" if not exist "%EXPECTED_FILE%" ( echo ERROR: Missing expected file "%EXPECTED_FILE%" >> "%LOG_FILE%" goto :skip_detection ) :: 执行检测 set "ACTUAL_FILE=result_%time:~0,2%-%time:~3,2%-%time:~6,2%.txt" adb shell "mount | grep mi_ext" > "!ACTUAL_FILE!" 2>&1 :: 文件比较逻辑(前两行模糊匹配,其他行精确匹配) set "STATUS=OK" if exist "!ACTUAL_FILE!" ( setlocal set "line_num=0" set "match_failed=0" for /f "usebackq tokens=*" %%A in ("!ACTUAL_FILE!") do ( set /a "line_num+=1" set "actual_line=%%A" if !line_num! gtr 2 ( findstr /x /c:"!actual_line!" "%EXPECTED_FILE%" >nul if !errorlevel! neq 0 set "match_failed=1" ) else ( call :fuzzy_compare "!actual_line!" "!line_num!" if !fuzzy_match! equ 0 set "match_failed=1" ) ) if !match_failed! equ 1 set "STATUS=ERROR" endlocal ) else ( set "STATUS=FAILED" ) :: 记录结果 ( echo/=== Check Result %date% %time% === echo/Status: %STATUS% echo/Total Checks: !TOTAL_COUNT! echo/Expected File: %EXPECTED_FILE% echo/Actual Output: !ACTUAL_FILE! echo/-------------------------------- type "!ACTUAL_FILE!" 2>nul echo/================================ ) >> "%LOG_FILE%" del "!ACTUAL_FILE!" 2>nul goto :show_result :: === 模糊匹配子程序 === :fuzzy_compare setlocal set "line=%~1" set "line_num=%~2" set "fuzzy_match=0" :: 生成模糊匹配模式(忽略数字变化) set "pattern=!line!" set "pattern=!pattern:0=#!" set "pattern=!pattern:1=#!" set "pattern=!pattern:2=#!" set "pattern=!pattern:3=#!" set "pattern=!pattern:4=#!" set "pattern=!pattern:5=#!" set "pattern=!pattern:6=#!" set "pattern=!pattern:7=#!" set "pattern=!pattern:8=#!" set "pattern=!pattern:9=#!" :: 在预期文件中查找匹配行 for /f "tokens=*" %%E in ('findstr /n . "%EXPECTED_FILE%"') do ( if "%%E" equ "!line_num!:!pattern!" set "fuzzy_match=1" ) endlocal & set "fuzzy_match=%fuzzy_match%" goto :eof :show_result :: 显示检测结果 cls echo ===== DEVICE PARTITION CHECK ===== echo [%TIME%] Check completed echo Device Status: Connected and Booted echo Partition Status: %STATUS% echo Total Checks: !TOTAL_COUNT! echo Log File: %LOG_FILE% echo. echo Continue monitoring in 5 seconds... timeout /t 5 >nul :: 返回主循环 goto :monitor_loop endlocal 优化这个脚本,验证发现逐行比较逻辑不生效,是否在比较错误时退出遍历?
最新发布
10-29
<insert id="batchSync"> INSERT INTO <foreach collection="sourceData" item="item" separator=" "> <if test="item.batteryId != null"> battery_${item.batteryId} </if> USING battery_info TAGS ( #{item.batteryId} ) VALUES <foreach collection="item.records" item="record" separator=","> ( #{record.ts}, #{record.batteryVoltage}, #{record.batteryCurrent}, #{record.batterySoc}, #{record.batteryWorkMode}, #{record.batteryErrorCode}, #{record.batteryTemperatureMax}, #{record.batteryTemperatureMin}, #{record.batteryVoltageMax}, #{record.batteryVoltageMin}, #{record.mosStatus}, #{record.mosTemp}, #{record.batteryCycleTimes}, #{record.longitude}, #{record.longitudeDirection}, #{record.latitude}, #{record.latitudeDirection}, #{record.gpsSignal}, #{record.flag}, #{record.handled}, #{record.payload}, #{record.imei}, #{record.iccid}, #{record.batteryKind}, #{record.projectId}, #{record.trackerSoftwareVersion}, #{record.batterySoftVersion}, #{record.sn}, #{record.soh}, #{record.cellVoltage}, #{record.batteryHardVersion}, #{record.batteryTemperatureAvg}, #{record.chargeCurrentMax}, #{record.dischargeCurrentMax}, #{record.chargeCurrentAvg}, #{record.dischargeCurrentAvg}, #{record.gpsCog}, #{record.gpsSpeed}, #{record.createTime}, #{record.updateTime} ) </foreach> </foreach> </insert> 对这条插入判空,实体类如下:@Data public class BatteryInfo{ private String batteryId; @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss.SSS",timezone = "GMT+8") private Timestamp ts; private Integer batteryVoltage; private Integer batteryCurrent; private Integer batterySoc; private String batteryWorkMode; private String batteryErrorCode; private Integer batteryTemperatureMax; private Integer batteryTemperatureMin; private Integer batteryVoltageMax; private Integer batteryVoltageMin; private Integer mosStatus; private Integer mosTemp; private Integer batteryCycleTimes; private String longitude; private String longitudeDirection; private String latitude; private String latitudeDirection; private String gpsSignal; private Integer flag; private Integer handled; private String payload; private String imei; private String iccid; private String batteryKind; private Integer projectId; private String trackerSoftwareVersion; private String batterySoftVersion; private String sn; private Integer soh; private String cellVoltage; private String batteryHardVersion; private Integer batteryTemperatureAvg; private Integer chargeCurrentMax; private Integer dischargeCurrentMax; private Integer chargeCurrentAvg; private Integer dischargeCurrentAvg; private String gpsCog; private String gpsSpeed; private Date createTime; private Date updateTime; @TableField(exist=false) private List<BatteryInfo> records; @TableField(exist=false) private Integer batteryVoltageRegion; @TableField(exist=false) private String batteryWorkModeValue; @TableField(exist=false) private String batteryErrorCodeValue; @TableField(exist=false) private String batteryErrorCodeDetails; @TableField(exist=false) private String dischargeMosStatusValue; @TableField(exist=false) private String chargeMosStatusValue; @TableField(exist=false) private String preDischargeMosStatusValue; @TableField(exist=false) private String balanceTubeStateValue; @TableField(exist=false) private String mosStatusValue; @TableField(exist=false) private String locationModeValue; @TableField(exist=false) private String locationMode; }
09-09
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值