Получить конкретную строку из каждой группы - PullRequest
0 голосов
/ 27 июня 2019

Мой вопрос очень похож на это , за исключением того, что я хочу иметь возможность фильтрации по некоторым критериям.

У меня есть таблица "ДОКУМЕНТ", которая выглядит примерно так:

|ID|CONFIG_ID|STATE     |MAJOR_REV|MODIFIED_ON|ELEMENT_ID|
+--+---------+----------+---------+-----------+----------+
| 1|1234     |Published | 2       |2019-04-03 | 98762    |
| 2|1234     |Draft     | 1       |2019-01-02 | 98762    |
| 3|5678     |Draft     | 3       |2019-01-02 | 24244    |
| 4|5678     |Published | 2       |2017-10-04 | 24244    |
| 5|5678     |Draft     | 1       |2015-05-04 | 24244    |

Это на самом деле еще несколько столбцов, но я пытаюсь сделать это простым.

Для каждого CONFIG_ID я хотел бы выбрать самый последний (MAX (MAJOR_REV) или MAX (MODIFIED_ON))) - но я могу захотеть отфильтровать по дополнительным критериям, таким как состояние (например, последняя опубликованная редакция документа) и / или дата (последняя редакция, опубликованная или нет) на определенную дату или: все документыгде ревизия была опубликована / изменена в пределах определенного интервала дат).

Чтобы сделать вещи более интересными, есть некоторые другие таблицы, к которым я хочу присоединиться.

Вот что у меня так далеко:

SELECT

        allDocs.ID,
        d.CONFIG_ID,
        d.[STATE],
        d.MAJOR_REV,
        d.MODIFIED_ON,
        d.ELEMENT_ID,
        f.ID FILE_ID,
        f.[FILENAME],
        et.COLUMN1,
        e.COLUMN2

FROM DOCUMENT -- Get all document revisions

CROSS APPLY (       -- Then for each config ID, only look at the latest revision
    SELECT TOP 1
        ID,
        MODIFIED_ON,
        CONFIG_ID,
        MAJOR_REV,
        ELEMENT_ID,
        [STATE]
    FROM DOCUMENT
    WHERE CONFIG_ID=allDocs.CONFIG_ID
    ORDER BY MAJOR_REV desc
) as d

LEFT OUTER JOIN ELEMENT e ON e.ID = d.ELEMENT_ID
LEFT OUTER JOIN ELEMENT_TYPE et ON e.ELEMENT_TYPE_ID=et.ID
LEFT OUTER JOIN TREE t ON t.NODE_ID = d.ELEMENT_ID

OUTER APPLY (   -- This is another optional 1:1 relation, but it's wrongfully implemented as m:n
        SELECT TOP 1
            FILE_ID
        FROM DOCUMENT_FILE_RELATION
        WHERE DOCUMENT_ID=d.ID
        ORDER BY MODIFIED_ON DESC
        ) as df -- There should never be more than 1, but we're using TOP 1 just in case, to avoid duplicates

LEFT OUTER JOIN [FILE] f on f.ID=df.FILE_ID

WHERE
    allDocs.CONFIG_ID = '5678' -- Just for testing purposes
    and d.state ='Released'  -- One possible filter criterion, there may be others

Похоже, что результаты верны, но возвращается несколько одинаковых строк.Я предполагаю, что для документов с 4 ревизиями одни и те же значения найдены 4 раза и возвращены.

Простой SELECT DISTINCT решил бы это, но я бы предпочел исправить свой запрос.

1 Ответ

0 голосов
/ 27 июня 2019

Я думаю, это будет классический номер строки и разделение на вопрос.

;with rows as
(
    select <your-columns>,
       row_number() over (partion by config_id order by <whatever you want>) as rn
    from document
    join <anything else>
    where <whatever>
 )
 select * from rows where rn=1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...