SQL - Как я могу получить верхнюю строку группы на основе меняющегося условия, не выбирая строки под ним? - PullRequest
0 голосов
/ 18 октября 2018

Скажем, я использовал запрос ниже:

select * from GenericTable order by ID, DATE

и получил следующую таблицу.

ID:     DATE:      VALUE1:       VALUE2:
----------------------------------------
 1     6/1/18           22            24
 1     7/1/18           23            25
 1     8/1/18           24            25
 2    6/28/18           31            46
 2    6/30/18           33            11
 2     7/1/18           21            10

Мне нужно уточнить этот запрос, чтобы выбрать только один datarow для IDна основании даты изменения условия (DATE <= @DateVar).Например, if @DateVar = '6/15/18', я должен получить следующую таблицу:

ID:     DATE:      VALUE1:       VALUE2:
----------------------------------------
 1     6/1/18           22            24

If @DateVar = 6/29, я должен получить:

ID:     DATE:      VALUE1:       VALUE2:
----------------------------------------
 1     6/1/18           22            24
 2    6/28/18           31            46

И если я сделаю @DateVar = 7/15, я долженget:

ID:     DATE:      VALUE1:       VALUE2:
----------------------------------------
 1     7/1/18           23            25
 2     7/1/18           21            10

Отслеживание Row# путем разбиения и выбора Row# = 1 было моим первоначальным решением, но как мне создать раздел, который составлял только DATE <= @DateVar, так что, скажем, @DateVar = 6/30, Я бы получил следующее, чтобы выбрать Row# = 1 из?

ID:     DATE:      VALUE1:       VALUE2:     ROW#:
--------------------------------------------------
 1     7/1/18           23            25         1
 1     8/1/18           24            25         2
 2    6/30/18           33            11         1
 2     7/1/18           21            10         2

Ответы [ 2 ]

0 голосов
/ 18 октября 2018

Я бы использовал row_number:

select top 1 with ties *
from GenericTable
where [DATE] <= @DateVar
order by row_number() over (partition by ID order by [DATE] desc)

Вот как вам помогает row_number ... Всякий раз, когда вам нужно вернуть всю строку, когда агрегат необходим только для части строки, тогда row_number (илидругие функции Windows).

Переместите row_number в выделенную часть и избавьтесь от верхней 1 со связями, чтобы увидеть, как на самом деле выглядит набор данных.

Большинство людей пишутэто так, но мне нравится, чтобы он выглядел крепче:

;with cte as 
(
select *,rn = row_number() over (partition by ID order by date desc)
from [table]
where [DATE] <= @DateVar
)
select * 
from cte 
where rn=1
0 голосов
/ 18 октября 2018

Дайте этому шанс ...

USE tempdb;
GO

IF OBJECT_ID('tempdb.dbo.Table_1', 'U') IS NOT NULL 
BEGIN DROP TABLE dbo.Table_1; END;

CREATE TABLE dbo.Table_1 (
    ID INT NOT NULL
        CONSTRAINT pk_table1 PRIMARY KEY
    );
INSERT dbo.Table_1 (ID) VALUES (1), (2);

IF OBJECT_ID('tempdb.dbo.Table_2', 'U') IS NOT NULL 
BEGIN DROP TABLE dbo.Table_2; END;

CREATE TABLE dbo.Table_2 (
    t1_ID INT NOT NULL
        CONSTRAINT fk_table2_t1ID FOREIGN KEY REFERENCES dbo.Table_1 (ID),
    SomeDate date NOT NULL,
    Value1 INT NOT NULL,
    Value2 INT NOT NULL,
    CONSTRAINT pk_table2 PRIMARY KEY (t1_ID, SomeDate) 
    );
INSERT dbo.Table_2 (t1_ID, SomeDate, Value1, Value2) VALUES 
    (1, '20180601', 22, 24),
    (1, '20180701', 23, 25),
    (1, '20180801', 24, 25),
    (2, '20180628', 31, 46),
    (2, '20180630', 33, 11),
    (2, '20180701', 21, 10);

--==================================================================

DECLARE @DateVar DATE = '20180710';

SELECT 
    t1.ID,
    tx.SomeDate,
    tx.Value1,
    tx.Value2
FROM
    dbo.Table_1 t1
    CROSS APPLY (
        SELECT TOP (1)
            t2  .t1_ID,
            t2.SomeDate,
            t2.Value1,
            t2.Value2
        FROM
            dbo.Table_2 t2
        WHERE 
            t1.ID = t2.t1_ID
            AND t2.SomeDate <= @DateVar
        ORDER BY 
            t2.SomeDate DESC
        ) tx;

Результат ...

ID          SomeDate   Value1      Value2
----------- ---------- ----------- -----------
1           2018-07-01 23          25
2           2018-07-01 21          10
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...