У меня есть такая процедура:
SELECT Name, Date, Par3, Date_rank
FROM
(SELECT Name, ROW_NUMBER() OVER (PARTITION BY Date ORDER BY Par3 ASC)
AS Date_rank
FROM Table
WHERE (..conditions..)) ranked
WHERE Par2_rank <= 3
ORDER BY Par2 ASC, Par3 ASC
Результат дает мне, если количество строк меньше или равно 3:
Name, Date, Par3, Date_rank
AB 2010-01-01 1.5 1
CD 2010-02-16 0.9 1
EF 2010-02-16 1.1 2
GH 2010-02-16 1.7 3
Но мне нужны только результаты, где у нас есть точное количество строк для даты, равное 3. Итак, результат должен быть:
Name, Date, Par3, Date_rank
CD 2010-02-16 0.9 1
EF 2010-02-16 1.1 2
GH 2010-02-16 1.7 3
Я пытался поставить WHERE Par2_rank = 3
.
Тогда я получаю только одну строку:
Name, Date, Par3, Date_rank
GH 2010-02-16 1.7 3
Также я пытался использовать HAVING COUNT
, но он не дает мне строк.
Заранее спасибо.
ОБНОВИТЬ: Спасибо всем вам, ребята, за быстрые ответы. COUNT (*) OVER PARTITION сделал свое дело. Это так просто... Надеюсь, благодаря вам в будущем я буду лучше писать код на SQL.
Демонстрационные данные лучше всего использовать как DDL + ДМЛ. Пожалуйста, редактировать ваш вопрос, чтобы включить его, вашу текущую попытку и желаемые результаты. Для получения дополнительной информации прочитай это.
Зоар, спасибо за подсказку. В следующий раз добавлю. Для этой темы я получил ответы так быстро, что опоздал с обновлением.
Если я правильно понял ваш вопрос, попробуйте следующий подход, используя SUM()
с предложением OVER
, но без ORDER BY
:
Вход:
CREATE TABLE #Table (
Name varchar(2),
[Date] date,
Par3 numeric(5, 1)
)
INSERT INTO #Table
(Name, [Date], Par3)
VALUES
('AB', '20100101', 1.5),
('AB', '20100101', 1.6),
('AB', '20100102', 1.5),
('AC', '20100102', 1.6),
('AD', '20100102', 1.7),
('AE', '20100102', 1.8),
('CD', '20100216', 0.9),
('EF', '20100216', 1.1),
('GH', '20100216', 1.7)
T-SQL:
SELECT Name, [Date], Par3, Rn
FROM (
SELECT
Name,
[Date],
Par3,
ROW_NUMBER() OVER (PARTITION BY [Date] ORDER BY Par3 ASC) AS Rn,
COUNT(*) OVER (PARTITION BY [Date]) As Cnt
FROM #Table
) ranked
WHERE Cnt = 3
Выход:
------------------------------
Name Date Par3 Rn
------------------------------
CD 2010-02-16 0.9 1
EF 2010-02-16 1.1 2
GH 2010-02-16 1.7 3
WITH cte_ranked
AS
(
SELECT Name, [Date], Par3
,COUNT(*) OVER (PARTITION BY [Date]) As DateCount
FROM Table
)
SELECT Name, [Date], Par3
FROM cte_ranked
WHERE DateCount = 3
ORDER BY [Date], Par3
Вы можете сделать это, используя EXISTS:
WITH ranked AS
(
SELECT Name, date, ROW_NUMBER() OVER (PARTITION BY Date ORDER BY Par3 ASC)
AS Date_rank
FROM Table
WHERE (..conditions..)
)
SELECT
*
FROM ranked AS R
WHERE EXISTS (SELECT 1
FROM ranked
where r.Date = Date
and Date_rank = 3
and Date_rank <> 4
)
Для первой строки есть дата `2010-01-01`, так что же в этом не так?