如何按范围 select 行?
How to select the rows by range?
我有以下 table 名为 'T'
我想要的输出应该如下所示,
我想要 select 列 'Actual' 的那些行的范围应该在列 'Basic'[=35 之间=],但是,如果您以 'Model' = HT65 为例
'Actual' = 23.2 的范围在列 'Basic' 的 22 和 24 之间,所以我应该得到行如下列'Level' 是 2
同样,其他行也应 selected。
您的帮助将不胜感激。
您可以使用以下解决方案,使用多个 LEFT JOIN
来连接当前行的下一行和最后一行。在一些附加条件下,您可以检查范围:
SELECT t1.Model, t1.Level, t1.Basic, t1.Actual
FROM (
SELECT *, ROW_NUMBER() OVER (PARTITION BY Model ORDER BY Basic) AS rn
FROM test
) t1 LEFT JOIN (
SELECT *, ROW_NUMBER() OVER (PARTITION BY Model ORDER BY Basic) AS rn
FROM test
) t2 ON t1.Model = t2.Model AND t1.rn + 1 = t2.rn LEFT JOIN (
SELECT *, ROW_NUMBER() OVER (PARTITION BY Model ORDER BY Basic) AS rn
FROM test
) t3 ON t1.Model = t3.Model AND t1.rn - 1 = t3.rn
WHERE (t1.Actual BETWEEN t3.Basic AND t1.Basic)
OR (t3.Model IS NULL AND t1.Actual < t1.Basic)
OR (t2.Model IS NULL AND t1.Actual > t1.Basic)
ORDER BY t1.Model ASC
以上查询获取了所有预期的行。我还添加了一些额外的案例来改进对这些(特殊)案例的查询。上述解决方案适用于 SQL-Server 2008.
自 SQL-Server 2012 年起,您可以通过 LAG
and LEAD
使用以下解决方案:
SELECT t.Model, t.Level, t.Basic, t.Actual
FROM (
SELECT *, LAG(Basic, 1,0) OVER (PARTITION BY Model ORDER BY Basic) AS prevBasic,
LEAD(Basic, 1, 0) OVER (PARTITION BY Model ORDER BY Basic) AS nextBasic
FROM test
) t
WHERE (t.Actual BETWEEN t.prevBasic AND t.Basic)
OR (t.nextBasic = 0 AND t.Actual > t.Basic)
ORDER BY t.Model ASC
我有以下 table 名为 'T'
我想要的输出应该如下所示,
我想要 select 列 'Actual' 的那些行的范围应该在列 'Basic'[=35 之间=],但是,如果您以 'Model' = HT65 为例 'Actual' = 23.2 的范围在列 'Basic' 的 22 和 24 之间,所以我应该得到行如下列'Level' 是 2
同样,其他行也应 selected。 您的帮助将不胜感激。
您可以使用以下解决方案,使用多个 LEFT JOIN
来连接当前行的下一行和最后一行。在一些附加条件下,您可以检查范围:
SELECT t1.Model, t1.Level, t1.Basic, t1.Actual
FROM (
SELECT *, ROW_NUMBER() OVER (PARTITION BY Model ORDER BY Basic) AS rn
FROM test
) t1 LEFT JOIN (
SELECT *, ROW_NUMBER() OVER (PARTITION BY Model ORDER BY Basic) AS rn
FROM test
) t2 ON t1.Model = t2.Model AND t1.rn + 1 = t2.rn LEFT JOIN (
SELECT *, ROW_NUMBER() OVER (PARTITION BY Model ORDER BY Basic) AS rn
FROM test
) t3 ON t1.Model = t3.Model AND t1.rn - 1 = t3.rn
WHERE (t1.Actual BETWEEN t3.Basic AND t1.Basic)
OR (t3.Model IS NULL AND t1.Actual < t1.Basic)
OR (t2.Model IS NULL AND t1.Actual > t1.Basic)
ORDER BY t1.Model ASC
以上查询获取了所有预期的行。我还添加了一些额外的案例来改进对这些(特殊)案例的查询。上述解决方案适用于 SQL-Server 2008.
自 SQL-Server 2012 年起,您可以通过 LAG
and LEAD
使用以下解决方案:
SELECT t.Model, t.Level, t.Basic, t.Actual
FROM (
SELECT *, LAG(Basic, 1,0) OVER (PARTITION BY Model ORDER BY Basic) AS prevBasic,
LEAD(Basic, 1, 0) OVER (PARTITION BY Model ORDER BY Basic) AS nextBasic
FROM test
) t
WHERE (t.Actual BETWEEN t.prevBasic AND t.Basic)
OR (t.nextBasic = 0 AND t.Actual > t.Basic)
ORDER BY t.Model ASC