我试图写下一个选项,向我展示我数据库中不存在的所有项目。假设我有一个名为TBL795的表,其中有一个名为NRBEM的列,其中没有任何空白。
应该是这样的:
这些数字是按顺序排列的。
如果他们看起来像这样:
他们错了,因为有些项目没有插入表格中。
在一个包含数千个项目的表格中,很难找出是否有任何空白,哪些是缺失的项目。
一个解决方案就是:
CREATE TABLE TESTE (
NRBEM VARCHAR(15))
用这样的命令喂它:
INSERT INTO TESTE
WITH RECURSIVE
cnt(NRBEM) AS (VALUES(1) UNION ALL SELECT NRBEM+1 FROM cnt WHERE NRBEM <100000)
SELECT NRBEM FROM cnt A
并运行此选择
SELECT A.NRBEM FROM TESTE A LEFT JOIN TBL795 B
ON A.NRBEM = B.NRBEM
WHERE B.NRBEM IS NULL
我可以看到表格中缺少的所有项目。
自命令:
WITH RECURSIVE
cnt(NRBEM) AS (VALUES(1) UNION ALL SELECT NRBEM+1 FROM cnt WHERE NRBEM <100000)
SELECT NRBEM FROM cnt
创建一个虚拟表我想运行这样的选择:
SELECT NRBEM FROM (
WITH RECURSIVE
cnt(NRBEM) AS (VALUES(1) UNION ALL SELECT NRBEM+1 FROM cnt WHERE NRBEM <100000)
SELECT NRBEM FROM cnt ) A LEFT JOIN TBL795 B
ON A.NRBEM = B.NRBEM
但这不起作用。
这样:
SELECT X FROM (
WITH RECURSIVE
cnt(X) AS (VALUES(1) UNION ALL SELECT X+1 FROM cnt WHERE X <100000)
SELECT X FROM cnt ) A LEFT JOIN TBL795 B
ON A.X = B.NRBEM
它有效,但没有选择正确的项目。
那么,我怎么能写这个选择?
答案 0 :(得分:1)
可以使用外连接并过滤匹配,但使用set操作更简单:
WITH RECURSIVE CNT(NRBEM) AS (...)
SELECT NRBEM
FROM CNT
WHERE NRBEM NOT IN (SELECT NRBEM
FROM tbl795);
答案 1 :(得分:0)
我发现了我做错了什么。
如果我将nrbem作为数字投射,则选择有效。
SELECT A.X FROM (
WITH RECURSIVE
cnt(X) AS (VALUES(1) UNION ALL SELECT X+1 FROM cnt WHERE X <100000)
SELECT X FROM cnt ) A LEFT JOIN ( SELECT CAST( NRBEM AS NUMBER ) AS NRBEM FROM TBL795 ) B
ON A.X = B.NRBEM
WHERE B.NRBEM IS NULL
如果我想检查项目2400到2700的范围,看看是否有任何差距,我可以这样做:
SELECT A.X FROM (
WITH RECURSIVE
cnt(X) AS (VALUES(2400) UNION ALL SELECT X+1 FROM cnt WHERE X < (2700))
SELECT X FROM cnt ) A LEFT JOIN ( SELECT CAST( NRBEM AS NUMBER ) AS NRBEM FROM TBL795 WHERE NRBEM >= 2400 and nrbem <= 2700 ) B
ON A.X = B.NRBEM
WHERE B.NRBEM IS NULL
LIMIT ( 2700 - 2400 + 1 )