У меня есть следующая таблица с именем «T»
Мой желаемый результат должен быть следующим:
Я хочу выбрать те строки, где столбец 'Действительный' должен иметь диапазон между столбцом 'Базовый', однако, если вы возьмете пример для 'Модель' = HT65 'Действительный' = 23.2, который имеет диапазон между 22 и 24 столбца 'Базовый', поэтому я должен получить следующую строку, где столбец 'Уровень' равен 2
Аналогичным образом должны быть выбраны другие строки. ваша помощь будет оценена по достоинству.
Я понятия не имею, о чем ваш вопрос. Возможно, вы захотите объяснить логику немного лучше.
Вы можете использовать следующее решение, используя несколько 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
и 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
что вы устали до сих пор?