Как выбрать возвращать только первую строку, когда в sql возвращается несколько строк

#sql #sql-server #tsql

#sql #sql-сервер #tsql

Вопрос:

У меня есть следующие данные:

 Id                                      Week1   Week2   Date
-------------------------------------------------------------------------------
C0935336-B424-E911-8117-005056A82772    201906  201904  2019-02-02 00:00:00.000
18D809B1-8725-E911-8117-005056A82772    201907  201904  2019-02-09 00:00:00.000
C95855A0-9428-E911-8117-005056A82772    201908  201905  2019-02-16 00:00:00.000
5ABE80F6-2531-E911-8117-005056A82772    201909  201905  2019-02-23 00:00:00.000
6B520DE4-9445-E911-8118-005056A82772    201910  201906  2019-03-02 00:00:00.000
ADD0A8D0-EE2E-E911-8117-005056A82772    201911  201906  2019-03-09 00:00:00.000
  

Как вы можете видеть, Week2 как повторяющиеся записи, и мне нужно вернуть первую строку каждой пары возвращаемых строк, чтобы в итоге получилось что-то похожее на это.

 Id                                      Week1   Week2   Date
-------------------------------------------------------------------------------
C0935336-B424-E911-8117-005056A82772    201906  201904  2019-02-02 00:00:00.000
C95855A0-9428-E911-8117-005056A82772    201908  201905  2019-02-16 00:00:00.000
6B520DE4-9445-E911-8118-005056A82772    201910  201906  2019-03-02 00:00:00.000
  

Я использую следующее в SQL:

 SELECT DISTINCT 
    ROW_NUMBER() OVER (PARTITION BY Weeks.Week2 ORDER BY Weeks.Week2) AS Row#, 
    Data.Id, Weeks.Week1, Weeks.Week2, Weeks.Date 
FROM
    Data
INNER JOIN 
    Weeks ON Data.WeekN = Weeks.Week1
INNER JOIN
    Users ON Data.UserId = Users.UserId
WHERE 
    Weeks.Week2 IN (SELECT DISTINCT Weeks.Week2
                    FROM Data
                    INNER JOIN Weeks ON Data.Week = Weeks.Week1
                    INNER JOIN Users ON Data.UserId = Users.UserId
                    WHERE Data.UserId = 1234 AND Weeks.Week1 >= 201907)
ORDER BY 
    Weeks.Week2
  

Который вводит номер строки для каждого набора или возвращаемых строк:

 Row# Id                                     Week1   Week2   Date
-----------------------------------------------------------------------------------
1    C0935336-B424-E911-8117-005056A82772   201906  201904  2019-02-02 00:00:00.000
2    18D809B1-8725-E911-8117-005056A82772   201907  201904  2019-02-09 00:00:00.000
1    C95855A0-9428-E911-8117-005056A82772   201908  201905  2019-02-16 00:00:00.000
2    5ABE80F6-2531-E911-8117-005056A82772   201909  201905  2019-02-23 00:00:00.000
1    6B520DE4-9445-E911-8118-005056A82772   201910  201906  2019-03-02 00:00:00.000
2    ADD0A8D0-EE2E-E911-8117-005056A82772   201911  201906  2019-03-09 00:00:00.000
  

Мой вопрос в том, как мне выбрать все строки, где Row# равно 1?

Комментарии:

1. Поместите другую SELECT вокруг того, что у вас уже есть. SELECT ... FROM (<your current query>) x WHERE x.row# = 1;

2. @stickybit Я понял это, но я удалил порядок, заставив его работать так, как если бы я его оставил, это выдает мне ошибку, но я думаю, что мне нужно оставить ее в: ‘Предложение ORDER BY недопустимо в представлениях, встроенных функциях, производных таблицах, подзапросах и общих табличных выражениях, если также не указано TOP, OFFSET или FOR XML. » Есть идеи?

3. ORDER BY В вашем ROW_NUMBER() выражении позаботится о порядке для вас. ORDER BY Предложение в запросе в этом случае не требуется.

Ответ №1:

Как упоминалось в @stickybit, вы можете использовать:

 SELECT
    Id
    , Week1
    , Week2
    , Date
FROM
    (
        SELECT
            ROW_NUMBER() OVER (PARTITION BY Weeks.Week2 ORDER BY Weeks.Week2) AS Row#
            , Data.Id
            , Weeks.Week1
            , Weeks.Week2
            , Weeks.Date
        FROM
            Data
            INNER JOIN Weeks ON Data.WeekN = Weeks.Week1
            INNER JOIN Users ON Data.UserId = Users.UserId
        WHERE Weeks.Week2 IN
            (
                SELECT DISTINCT Weeks.Week2
                FROM
                    Data
                    INNER JOIN Weeks ON Data.Week = Weeks.Week1
                    INNER JOIN Users ON Data.UserId = Users.UserId
                WHERE
                    Data.UserId = 1234
                    AND Weeks.Week1 >= 201907
            )
    ) Q
WHERE Row# = 1
  

Вам не нужно беспокоиться о ORDER BY , так как ROW_NUMBER() функция позаботится об этом за вас в своем OVER() предложении.

Вам также не нужно, DISTINCT поскольку ROW_NUMBER() функция в любом случае не даст ей никакого эффекта.