SQL SERVER中EXCEPT/INTERSECT,CASE/ISNULL/COALESCE

SQL Server 查询技巧
本文介绍了SQL Server中的EXCEPT和INTERSECT操作符的用法,它们用于比较两个查询的结果并返回非重复值。同时,文章还对比了CASE、ISNULL和COALESCE的功能差异。

SQL SERVER中EXCEPT/INTERSECT,CASE/ISNULL/COALESCE


EXCEPT 和 INTERSECT


一般解释:比较两个查询的结果,返回非重复值。

EXCEPT 从左查询中返回右查询没有找到的所有非重复值。

INTERSECT 返回 左右两边的两个查询都包含的所有非重复值。

以下是将使用 EXCEPT 或 INTERSECT 的两个查询的结果集组合起来的基本规则:

  • 所有查询中的列数和列的顺序必须相同。

  • 数据类型必须兼容。

假设test表中testid包含1,1,2,3,4,4;test2表中id包含1,2,3,4,5,6

select testid from test
intersect
select id from test2

结果只有1,2,3,4。

select id from test2
except
select testid from test


结果只有5,6.


对比CASE, ISNULL, COALESCE


ISNULL和COALESCE大体上相同,相当于CASE 语句:

CASE

   WHEN (expression1 IS NOT NULL) THEN expression1

   WHEN (expression2 IS NOT NULL) THEN expression2

   ...

   ELSE expressionN

END

ISNULLCOALESCE还是不同的。

SELECT ISNULL(NULL,NULL)返回NULL。

SELECT COALESCE(NULL,NULL)则报错:至少有一个参数不能为空。

ISNULL只能有两个参数,如ISNULL(1,NULL),而COALESCE则可以有多个参数,如COALESCE(NULL,3,NULL,1)。

ISNULL最终返回值类型跟第一个参数类型相同。如果两个参数的类型不同并最终返回值等于第二个参数,则会把第二个参数进行隐式转换为第一个参数的类型再返回。

如,

DECLARE @Field1 char(4), @Field2 char(50)
SET @Field2 = 'LeeWhoee University'
SELECT ISNULL(@Field1, @Field2)
--返回 'LeeW'
SELECT COALESCE(@Field1, @Field2)
--返回 'LeeWhoee University'



执行SampleQuery失败,请检查计算列 Related Dashboard: '【复制】CrossDock预约数据监控看板20250915184802-1338' Related Query: '集散中心_CK数据' Run user: 'h84388317' Caused by: java.sql.SQLException 执行SQL失败:“PARSE ERROR: Failure parsing the query. SQL Query SELECT "运维负责人", "检验负责人", "流速", "转质检周期", "检验周期", "上架周期", "创单周期", "拣料周期", "状态", "滞留天数", "物料大类", "收月", "收日", "发月", "发日", "收周", "发周", "外部入库单号", "条码", lpn, "物料编码", "数量", "是否需要质检", "质检结果", "lpn状态", "收货时间", "转质检时间", "质检完成时间", "退货提交时间", "上架时间", "库区", "收货月", "收货天", "收货周", "数据平台调度时间", "外部出库单号", "交付对象", "状态0", "条码0", "自lpn", "拣货量", "创建时间", "拣货开始时间", "最后更新时间", "发货月", "发货天", "发货周", "ASN单号", "供应商名称", NULL AS "填充", IF("退货提交时间" IS NOT NULL, DATEDIFF("质检完成时间", "退货提交时间"), DATEDIFF("质检完成时间", NOW())) AS "不合格流速", CONCAT("收周", '周') AS "收货周数", CONCAT("发周", '周') AS "发货周数", CONCAT(CONCAT(CONCAT("发月", '月'), "发日"), '日') AS "发货月日", CONCAT(CONCAT(CONCAT("收月", '月'), "收日"), '日') AS "收货月日" FROM (SELECT * FROM (SELECT CASE WHEN LEFT(物料编码, 2) = '23' THEN '李晨辉' WHEN LEFT(物料编码, 4) = '0222' THEN '朱亮' ELSE '舒利文' END AS 运维负责人, CASE WHEN LEFT(物料编码, 2) = '23' THEN '杨先丽' WHEN LEFT(物料编码, 4) = '0222' THEN '刘芳' ELSE '张广一' END AS 检验负责人, CASE WHEN 质检结果 = '合格' THEN TIMESTAMPDIFF(MINUTE, 收货时间, 最后更新时间) / 60.0 WHEN 质检结果 = '不合格' AND 退货提交时间 IS NULL THEN TIMESTAMPDIFF(MINUTE, 收货时间, 数据平台调度时间) / 60.0 WHEN 质检结果 = '不合格' AND 退货提交时间 IS NOT NULL THEN TIMESTAMPDIFF(MINUTE, 收货时间, 退货提交时间) / 60.0 WHEN 质检结果 = '待检' THEN TIMESTAMPDIFF(MINUTE, 收货时间, 数据平台调度时间) / 60.0 WHEN 质检结果 IS NULL AND 拣货开始时间 IS NULL THEN TIMESTAMPDIFF(MINUTE, 收货时间, 数据平台调度时间) / 60.0 WHEN 质检结果 IS NULL AND 拣货开始时间 IS NOT NULL THEN TIMESTAMPDIFF(MINUTE, 收货时间, 最后更新时间) / 60.0 END AS 流速, CASE WHEN 转质检时间 IS NOT NULL THEN TIMESTAMPDIFF(MINUTE, 收货时间, 转质检时间) / 60.0 END AS 转质检周期, CASE WHEN 转质检时间 IS NOT NULL THEN TIMESTAMPDIFF(MINUTE, 转质检时间, 质检完成时间) / 60.0 WHEN 转质检时间 IS NULL THEN TIMESTAMPDIFF(MINUTE, 收货时间, 质检完成时间) / 60.0 END AS 检验周期, CASE WHEN 转质检时间 IS NOT NULL THEN TIMESTAMPDIFF(MINUTE, 质检完成时间, 上架时间) / 60.0 WHEN 转质检时间 IS NULL THEN TIMESTAMPDIFF(MINUTE, 收货时间, 上架时间) / 60.0 END AS 上架周期, CASE WHEN 转质检时间 IS NOT NULL THEN TIMESTAMPDIFF(MINUTE, 上架时间, 创建时间) / 60.0 END AS 创单周期, CASE WHEN 转质检时间 IS NOT NULL THEN TIMESTAMPDIFF(MINUTE, 创建时间, 最后更新时间) / 60.0 END AS 拣料周期, CASE WHEN 质检结果 = '合格' AND 拣货开始时间 IS NULL THEN '待出库' WHEN 质检结果 = '合格' AND 拣货开始时间 IS NOT NULL THEN '已出库' WHEN 质检结果 = '不合格' AND 退货提交时间 IS NULL THEN '待退货' WHEN 质检结果 = '不合格' AND 退货提交时间 IS NOT NULL THEN '已退货' WHEN 质检结果 = '待检' THEN '待检验' WHEN 质检结果 IS NULL AND 拣货开始时间 IS NULL THEN '待出库' WHEN 质检结果 IS NULL AND 拣货开始时间 IS NOT NULL THEN '已出库' END AS 状态, CASE WHEN 拣货开始时间 IS NOT NULL THEN TIMESTAMPDIFF(HOUR, 收货时间, 最后更新时间) / 24 ELSE TIMESTAMPDIFF(HOUR, 收货时间, 数据平台调度时间) / 24 END AS 滞留天数, CASE WHEN LEFT(物料编码, 4) = '0222' THEN '电源' WHEN LEFT(物料编码, 4) = '5199' THEN '皮套/PC壳' WHEN LEFT(物料编码, 2) = '23' THEN '显示屏' ELSE '结构件' END AS 物料大类, LPAD(CAST(收货月 AS VARCHAR (2)), 2, '0') AS 收月, LPAD(CAST(收货天 AS VARCHAR (2)), 2, '0') AS 收日, LPAD(CAST(发货月 AS VARCHAR (2)), 2, '0') AS 发月, LPAD(CAST(发货天 AS VARCHAR (2)), 2, '0') AS 发日, LPAD(CAST(收货周 AS VARCHAR (2)), 2, '0') AS 收周, LPAD(CAST(发货周 AS VARCHAR (2)), 2, '0') AS 发周, * FROM (SELECT 外部入库单号, t."09码" AS 条码, lpn, 物料编码, 数量, 是否需要质检, 质检结果, lpn状态, 收货时间, 转质检时间, 质检完成时间, 退货提交时间, 上架时间, 库区, MONTH(收货时间) AS 收货月, DAYOFMONTH(收货时间) AS 收货天, WEEK(收货时间) AS 收货周, 数据平台调度时间 FROM "cwms3_receive_kpi_rmcc_v" AS t WHERE 外部入库单号 LIKE '%R25%') AS t1 LEFT OUTER JOIN (SELECT 外部出库单号, 交付对象, 状态, 条码, 自lpn, 拣货量, 创建时间, 拣货开始时间, 最后更新时间, MONTH(拣货开始时间) AS 发货月, DAYOFMONTH(拣货开始时间) AS 发货天, WEEK(拣货开始时间) AS 发货周 FROM "cwms3_pick_task_d_rmcc_v") AS t2 ON t1.lpn = t2.自lpn) AS t3 LEFT OUTER JOIN (SELECT ASN单号, 供应商名称 FROM "asn_shipment_line_v") AS t4 ON t3.外部入库单号 = t4.ASN单号 WHERE 外部入库单号 NOT IN ('R25809AB4', 'R25814AAR', 'R25815AAQ', 'R25815AB4', 'R25816AAV', 'R25817AB2', 'R25817AB4', 'R25819AAT', 'R25826AB5', 'R25828AA2', 'R25901AA4', 'R25902AA3', 'R25903AAS', 'R25904AAR', 'R25905ABG', 'R25906AB2', 'R25906AB4', 'R25907AA2', 'R25907AA4', 'R25907AAC', 'R25907AB3', 'R25907AB6', 'R25909AA1', 'R25909AB1', 'R25909AB8')) SUB_QRY /*JDBC,1ea2039a-971f-45ee-8e56-81399ae9d88d,762d8d64-6dcf-4397-a7df-188778a8f6b2,e84b5596-bbef-4586-b54e-a0e88b916daa*/ startLine 1 startColumn 403 endLine 1 endColumn 403 SQL Query SELECT "运维负责人", "检验负责人", "流速", "转质检周期", "检验周期", "上架周期", "创单周期", "拣料周期", "状态", "滞留天数", "物料大类", "收月", "收日", "发月", "发日", "收周", "发周", "外部入库单号", "条码", lpn, "物料编码", "数量", "是否需要质检", "质检结果", "lpn状态", "收货时间", "转质检时间", "质检完成时间", "退货提交时间", "上架时间", "库区", "收货月", "收货天", "收货周", "数据平台调度时间", "外部出库单号", "交付对象", "状态0", "条码0", "自lpn", "拣货量", "创建时间", "拣货开始时间", "最后更新时间", "发货月", "发货天", "发货周", "ASN单号", "供应商名称", NULL AS "填充", IF("退货提交时间" IS NOT NULL, DATEDIFF("质检完成时间", "退货提交时间"), DATEDIFF("质检完成时间", NOW())) AS "不合格流速", CONCAT("收周", '周') AS "收货周数", CONCAT("发周", '周') AS "发货周数", CONCAT(CONCAT(CONCAT("发月", '月'), "发日"), '日') AS "发货月日", CONCAT(CONCAT(CONCAT("收月", '月'), "收日"), '日') AS "收货月日" FROM (SELECT * FROM (SELECT CASE WHEN LEFT(物料编码, 2) = '23' THEN '李晨辉' WHEN LEFT(物料编码, 4) = '0222' THEN '朱亮' ELSE '舒利文' END AS 运维负责人, CASE WHEN LEFT(物料编码, 2) = '23' THEN '杨先丽' WHEN LEFT(物料编码, 4) = '0222' THEN '刘芳' ELSE '张广一' END AS 检验负责人, CASE WHEN 质检结果 = '合格' THEN TIMESTAMPDIFF(MINUTE, 收货时间, 最后更新时间) / 60.0 WHEN 质检结果 = '不合格' AND 退货提交时间 IS NULL THEN TIMESTAMPDIFF(MINUTE, 收货时间, 数据平台调度时间) / 60.0 WHEN 质检结果 = '不合格' AND 退货提交时间 IS NOT NULL THEN TIMESTAMPDIFF(MINUTE, 收货时间, 退货提交时间) / 60.0 WHEN 质检结果 = '待检' THEN TIMESTAMPDIFF(MINUTE, 收货时间, 数据平台调度时间) / 60.0 WHEN 质检结果 IS NULL AND 拣货开始时间 IS NULL THEN TIMESTAMPDIFF(MINUTE, 收货时间, 数据平台调度时间) / 60.0 WHEN 质检结果 IS NULL AND 拣货开始时间 IS NOT NULL THEN TIMESTAMPDIFF(MINUTE, 收货时间, 最后更新时间) / 60.0 END AS 流速, CASE WHEN 转质检时间 IS NOT NULL THEN TIMESTAMPDIFF(MINUTE, 收货时间, 转质检时间) / 60.0 END AS 转质检周期, CASE WHEN 转质检时间 IS NOT NULL THEN TIMESTAMPDIFF(MINUTE, 转质检时间, 质检完成时间) / 60.0 WHEN 转质检时间 IS NULL THEN TIMESTAMPDIFF(MINUTE, 收货时间, 质检完成时间) / 60.0 END AS 检验周期, CASE WHEN 转质检时间 IS NOT NULL THEN TIMESTAMPDIFF(MINUTE, 质检完成时间, 上架时间) / 60.0 WHEN 转质检时间 IS NULL THEN TIMESTAMPDIFF(MINUTE, 收货时间, 上架时间) / 60.0 END AS 上架周期, CASE WHEN 转质检时间 IS NOT NULL THEN TIMESTAMPDIFF(MINUTE, 上架时间, 创建时间) / 60.0 END AS 创单周期, CASE WHEN 转质检时间 IS NOT NULL THEN TIMESTAMPDIFF(MINUTE, 创建时间, 最后更新时间) / 60.0 END AS 拣料周期, CASE WHEN 质检结果 = '合格' AND 拣货开始时间 IS NULL THEN '待出库' WHEN 质检结果 = '合格' AND 拣货开始时间 IS NOT NULL THEN '已出库' WHEN 质检结果 = '不合格' AND 退货提交时间 IS NULL THEN '待退货' WHEN 质检结果 = '不合格' AND 退货提交时间 IS NOT NULL THEN '已退货' WHEN 质检结果 = '待检' THEN '待检验' WHEN 质检结果 IS NULL AND 拣货开始时间 IS NULL THEN '待出库' WHEN 质检结果 IS NULL AND 拣货开始时间 IS NOT NULL THEN '已出库' END AS 状态, CASE WHEN 拣货开始时间 IS NOT NULL THEN TIMESTAMPDIFF(HOUR, 收货时间, 最后更新时间) / 24 ELSE TIMESTAMPDIFF(HOUR, 收货时间, 数据平台调度时间) / 24 END AS 滞留天数, CASE WHEN LEFT(物料编码, 4) = '0222' THEN '电源' WHEN LEFT(物料编码, 4) = '5199' THEN '皮套/PC壳' WHEN LEFT(物料编码, 2) = '23' THEN '显示屏' ELSE '结构件' END AS 物料大类, LPAD(CAST(收货月 AS VARCHAR (2)), 2, '0') AS 收月, LPAD(CAST(收货天 AS VARCHAR (2)), 2, '0') AS 收日, LPAD(CAST(发货月 AS VARCHAR (2)), 2, '0') AS 发月, LPAD(CAST(发货天 AS VARCHAR (2)), 2, '0') AS 发日, LPAD(CAST(收货周 AS VARCHAR (2)), 2, '0') AS 收周, LPAD(CAST(发货周 AS VARCHAR (2)), 2, '0') AS 发周, * FROM (SELECT 外部入库单号, t."09码" AS 条码, lpn, 物料编码, 数量, 是否需要质检, 质检结果, lpn状态, 收货时间, 转质检时间, 质检完成时间, 退货提交时间, 上架时间, 库区, MONTH(收货时间) AS 收货月, DAYOFMONTH(收货时间) AS 收货天, WEEK(收货时间) AS 收货周, 数据平台调度时间 FROM "cwms3_receive_kpi_rmcc_v" AS t WHERE 外部入库单号 LIKE '%R25%') AS t1 LEFT OUTER JOIN (SELECT 外部出库单号, 交付对象, 状态, 条码, 自lpn, 拣货量, 创建时间, 拣货开始时间, 最后更新时间, MONTH(拣货开始时间) AS 发货月, DAYOFMONTH(拣货开始时间) AS 发货天, WEEK(拣货开始时间) AS 发货周 FROM "cwms3_pick_task_d_rmcc_v") AS t2 ON t1.lpn = t2.自lpn) AS t3 LEFT OUTER JOIN (SELECT ASN单号, 供应商名称 FROM "asn_shipment_line_v") AS t4 ON t3.外部入库单号 = t4.ASN单号 WHERE 外部入库单号 NOT IN ('R25809AB4', 'R25814AAR', 'R25815AAQ', 'R25815AB4', 'R25816AAV', 'R25817AB2', 'R25817AB4', 'R25819AAT', 'R25826AB5', 'R25828AA2', 'R25901AA4', 'R25902AA3', 'R25903AAS', 'R25904AAR', 'R25905ABG', 'R25906AB2', 'R25906AB4', 'R25907AA2', 'R25907AA4', 'R25907AAC', 'R25907AB3', 'R25907AB6', 'R25909AA1', 'R25909AB1', 'R25909AB8')) SUB_QRY /*JDBC,1ea2039a-971f-45ee-8e56-81399ae9d88d,762d8d64-6dcf-4397-a7df-188778a8f6b2,e84b5596-bbef-4586-b54e-a0e88b916daa*/ [Error Id: 0cac497f-ceb7-4fe8-b453-a2a610b1c82a on localhost:31010] (org.apache.calcite.sql.parser.SqlParseException) Encountered ", IF" at line 1, column 403. Was expecting one of: "ORDER" ... "LIMIT" ... "OFFSET" ... "FETCH" ... ";" ... "FROM" ... "," "*" ... "," "+" ... "," "-" ... "," "NOT" ... "," "EXISTS" ... "," ... "," ... "," ... "," ... "," ... "," ... "," ... "," "TRUE" ... "," "FALSE" ... "," "UNKNOWN" ... "," "NULL" ... "," ... "," ... "," ... "," "DATE" ... "," "TIME" ... "," "TIMESTAMP" ... "," "INTERVAL" ... "," "CONTAINS(" ... "," "?" ... "," "CAST" ... "," "EXTRACT" ... "," "POSITION" ... "," "CONVERT" ... "," "TRANSLATE" ... "," "OVERLAY" ... "," "FLOOR" ... "," "CEIL" ... "," "CEILING" ... "," "SUBSTRING" ... "," "TRIM" ... "," "CLASSIFIER" ... "," "MATCH_NUMBER" ... "," "RUNNING" ... "," "PREV" ... "," "NEXT" ... "," ... "," "MULTISET" ... "," "ARRAY" ... "," "PERIOD" ... "," "SPECIFIC" ... "," ... "," ... "," ... "," ... "," ... "," "ABS" ... "," "AVG" ... "," "CARDINALITY" ... "," "CHAR_LENGTH" ... "," "CHARACTER_LENGTH" ... "," "COALESCE" ... "," "COLLECT" ... "," "COVAR_POP" ... "," "COVAR_SAMP" ... "," "CUME_DIST" ... "," "COUNT" ... "," "CURRENT_DATE" ... "," "CURRENT_TIME" ... "," "CURRENT_TIMESTAMP" ... "," "DENSE_RANK" ... "," "ELEMENT" ... "," "EXP" ... "," "FIRST_VALUE" ... "," "FUSION" ... "," "GROUPING" ... "," "HOUR" ... "," "LAG" ... "," "LEAD" ... "," "LEFT" ... "," "LAST_VALUE" ... "," "LN" ... "," "LOCALTIME" ... "," "LOCALTIMESTAMP" ... "," "LOWER" ... "," "MAX" ... "," "MIN" ... "," "MINUTE" ... "," "MOD" ... "," "MONTH" ... "," "NTH_VALUE" ... "," "NTILE" ... "," "NULLIF" ... "," "OCTET_LENGTH" ... "," "PERCENT_RANK" ... "," "PERCENTILE_CONT" ... "," "PERCENTILE_DISC" ... "," "POWER" ... "," "RANK" ... "," "REGR_SXX" ... "," "REGR_SYY" ... "," "RIGHT" ... "," "ROW_NUMBER" ... "," "SECOND" ... "," "SQRT" ... "," "STDDEV_POP" ... "," "STDDEV_SAMP" ... "," "SUM" ... "," "UPPER" ... "," "TRUNCATE" ... "," "USER" ... "," "VAR_POP" ... "," "VAR_SAMP" ... "," "YEAR" ... "," "CURRENT_CATALOG" ... "," "CURRENT_DEFAULT_TRANSFORM_GROUP" ... "," "CURRENT_PATH" ... "," "CURRENT_ROLE" ... "," "CURRENT_SCHEMA" ... "," "CURRENT_USER" ... "," "SESSION_USER" ... "," "SYSTEM_USER" ... "," "NEW" ... "," "CASE" ... "," "CURRENT" ... "," "CURSOR" ... "," "ROW" ... "," "(" ... "UNION" ... "INTERSECT" ... "EXCEPT" ... "MINUS" ... com.dremio.exec.planner.sql.parser.impl.ParserImpl.convertException():347 com.dremio.exec.planner.sql.parser.impl.ParserImpl.normalizeException():140 org.apache.calcite.sql.parser.SqlParser.handleException():133 org.apache.calcite.sql.parser.SqlParser.parseStmtList():188 com.dremio.exec.planner.sql.SqlConverter.parseMultipleStatementsImpl():174 com.dremio.exec.planner.sql.SqlConverter.parseSingleStatementImpl():189 com.dremio.exec.planner.sql.SqlConverter.parse():201 com.dremio.exec.planner.sql.handlers.commands.CommandCreator.getSqlCommand():300 com.dremio.exec.planner.sql.handlers.commands.CommandCreator.toCommand():252 com.dremio.exec.work.foreman.AttemptManager.plan():494 com.dremio.exec.work.foreman.AttemptManager.lambda$run$4():400 com.dremio.service.commandpool.ReleasableBoundCommandPool.lambda$getWrappedCommand$3():137 com.dremio.service.commandpool.CommandWrapper.run():62 com.dremio.context.RequestContext.run():96 com.dremio.common.concurrent.ContextMigratingExecutorService.lambda$decorate$3():199 com.dremio.common.concurrent.ContextMigratingExecutorService$ComparableRunnable.run():180 java.util.concurrent.Executors$RunnableAdapter.call():511 java.util.concurrent.FutureTask.run():266 java.util.concurrent.ThreadPoolExecutor.runWorker():1149 java.util.concurrent.ThreadPoolExecutor$Worker.run():624 java.lang.Thread.run():748 ” 报错
最新发布
09-16
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值