WITH CTE AS
(
SELECT
*,
ROW_NUMBER() OVER (PARTITION BY id ORDER BY opened_at) RN
FROM
table
)
SELECT column1, column2
FROM CTE
WHERE RN = 2
Если RN = 2 нет, как я могу вместо него вернуть RN = 1?
Если я кодирую что-то вроде
WHERE RN = IIF (RN = 2,2,1)
он вернет как RN = 1, так и RN = 2 для строк, содержащих 1 и 2. Мне нужен только RN = 2 или RN = 1, если RN = 2 не существует.
Любые предложения будут высоко оценены.
Спасибо!
Можете ли вы показать примеры данных с ожидаемым результатом?
Всегда ли есть одна или две строки или вы хотите, чтобы строка 2 возвращалась в случае, если есть две или более строк?
@HABO да, почти всегда существует более двух строк для одного и того же идентификатора, поэтому в таком сценарии мне нужно вернуть строку 2, но если есть только одна строка, то мне нужно вернуть строку 1. ВалНик поделился отличной идеей ниже использовать не только функцию row_number, но и count (*). Я думаю, это должно дать мне то, что мне нужно :)


Вы можете сделать это, получив max rn для каждого идентификатора, где max rn <= 2, а затем применив соединение, чтобы получить ожидаемый результат:
WITH CTE AS (
SELECT *, ROW_NUMBER () OVER (PARTITION BY id ORDER BY opened_at) RN
FROM mytable
)
SELECT c.*
FROM CTE c
INNER JOIN (
SELECT id, max(rn) as max_rn
FROM CTE
where rn <= 2
GROUP BY id
) as s on s.id = c.id and s.max_rn = c.rn
Вы можете подсчитывать строки в разделе по идентификатору. Если там 1 строка (count=1), то rn=1 — делать нечего. Если count>1, тогда возьмите RN=2.
Попробуй это
WITH CTE AS (
SELECT *, ROW_NUMBER () OVER (PARTITION BY id ORDER BY opened_at) RN
, count (*) OVER (PARTITION BY id) qty
FROM table)
SELECT column1, column2
FROM CTE
WHERE (qty>1 and RN = 2) or (qty=1)
Попробуйте изменить порядок, нажав
OVER (PARTITION BY id ORDER BY opened_at DESC) RN, а затемWHERE RN=1. В случае, когда rn может быть в (1,2) или (1), это помогает.