SQL专家的快速提问.
我有一个表,个中包括两列-min_number和max_number 我一向在实行写一个查询,但未乐成找到最小和最大数字之间的第n个孔
例
min max
1. 100 200
2. 250 300
3. 330 400
假如我想找到一个巨细为50的孔,则将返回第1行的最大值200(在第2行的最小值和第2行的最小值之间有50的孔),第20行的孔将返回第2s的最大值300,以此类推. 假如不存在吻合巨细的孔,则将返回最后的最大值(400).
感谢
最佳谜底
编辑:最终谜底在底部.
为什么这么多SQL题目健忘了表名?
-- Buggy: should reference (lo.max + 1)
SELECT lo.max + 1 AS min_range
FROM example lo,example hi
WHERE hi.min - (lo.max - 1) >= 40 -- Example won't work with 50
AND NOT EXISTS (SELECT * FROM example AS mid
WHERE mid.min > lo.max
AND mid.max < hi.min
)
NOT EXISTS子句至关重要-它确保您仅思量相邻范畴.
这涉及“差距足够大”的环境.
名义上,您可以行使UNION子句处理赏罚“没有足够大的间隙”:
...
UNION
SELECT MAX(max)+1
FROM example
WHERE NOT EXISTS(
SELECT lo.max + 1 AS min_range
FROM example lo,example hi
WHERE hi.min - (lo.max - 1) >= 40 -- Example won't work with 50
AND NOT EXISTS (SELECT * FROM example AS mid
WHERE mid.min > lo.max
AND mid.max < hi.min
)
)
内部SELECT是第一个缩进的直接转录.
上面的SQL未经测试.第一部门事变(尤其是在测试数据上)-可是可以发生多个谜底.因此,必要将其修订为(我以为,批改了二分之一错误):
SELECT MIN(lo.max + 1) AS min_range
FROM example lo,example hi
WHERE hi.min - (lo.max + 1) >= 40 -- Example won't work with 50
AND NOT EXISTS (SELECT * FROM example AS mid
WHERE mid.min > lo.max
AND mid.max < hi.min
)
UNION子句让我有些哀痛…没有发生我祈望的谜底.
在语法上,我必需将其修改为:
SELECT MIN(lo.max + 1) AS min_range
FROM example lo,example hi
WHERE hi.min - (lo.max + 1) >= 40 -- Example won't work with 50
AND NOT EXISTS (SELECT * FROM example AS mid
WHERE mid.min > lo.max
AND mid.max < hi.min
)
UNION
SELECT MAX(solo.max)+1
FROM example AS solo
WHERE NOT EXISTS(
SELECT MIN(lo.max + 1) AS min_range
FROM example lo,example hi
WHERE hi.min - (lo.max - 1) >= 40 -- Example won't work with 50
AND NOT EXISTS (SELECT * FROM example AS mid
WHERE mid.min > lo.max
AND mid.max < hi.min
)
)
这可以停止行使要害字MAX作为列名的题目(我也许写了example.max而不是solo.max.可是它并没有发生我祈望的谜底.
在这种环境下,UNION等效于OR,而且此查询好像发生了我想要的谜底:
SELECT MIN(lo.max + 1) AS min_range
FROM example lo,example hi
WHERE (hi.min - (lo.max + 1) >= 40
AND NOT EXISTS (SELECT * FROM example AS mid
WHERE mid.min > lo.max
AND mid.max < hi.min
)
)
OR lo.max = (SELECT MAX(solo.max) FROM Example AS Solo)
;
至关重要的是,OR子句引用lo.max而不是hi.max.不然,您将获得错误的谜底.
OK-UNION版本注定要失败,由于SQL错误界说了MIN的举动.详细来说,假如没有匹配的行,则MIN返回值为NULL的一行,而不返回任何行.这意味着,在未找到任何行的环境下,UNION的第一子句将返回NULL.第二个子句可以通过在NOT EXISTS内部省略SELECT中的MIN来“牢靠”,可是您如故从语句中获得两行(NULL和正确值),这现实上是不行接管的.因此,OR版本是要行使的版本-SQL再次行使NULL值举办咬合.
可以通过在FROM子句中的表表达式中结构UNION来严酷停止行使null.最终会变得轻微简朴一些:
SELECT MIN(min_range)
FROM (SELECT (lo.max + 1) AS min_range
FROM example lo,example hi
WHERE hi.min - (lo.max + 1) >= 49
AND NOT EXISTS (SELECT * FROM example AS mid
WHERE mid.min > lo.max
AND mid.max < hi.min
)
UNION
SELECT MAX(solo.max + 1) AS min_range
FROM example AS solo
);
UNION的前半部门可以返回恣意数目的时隙,包罗零;第二个老是返回一个值(只要表中有任何行).然后,外部查询选择这些值中的最低者.
虽然,此版本可用于分派行:
INSERT INTO Example(min,max)
SELECT MIN(min_range) AS min,MIN(min_range) + (50 - 1) AS max
FROM (SELECT (lo.max + 1) AS min_range
FROM example lo,example hi
WHERE hi.min - (lo.max + 1) >= 50
AND NOT EXISTS (SELECT * FROM example mid
WHERE mid.min > lo.max
AND mid.max < hi.min
)
UNION
SELECT MAX(solo.max + 1) AS min_range
FROM example AS solo
);
(编辑:湖南网)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|