2009-09-24 7 views
1

Я пытаюсь понять необычное поведение видны при заказе результатов в убывающем порядке с помощью функции() в row_number при использовании DISITINCT на внешнем выбрать в моем запросе, как показано ниже:SQL Server 2005 - row_number()

SELECT DISTINCT (ID), State_Id, Name_Of_Trip, Date_Of_Travel, Creation_Date, Locking_Id, Applicant_Name, Reference_Number, State_Name 
    FROM (

    SELECT app.ID, app.State_Id, app.Name_Of_Trip, app.Date_Of_Travel, app.Creation_Date, app.Locking_Id, app.Applicant_Name, app.Reference_Number, 
    State.Name AS State_Name, ROW_NUMBER() OVER(ORDER BY Reference_Number DESC) as rowNum 
    FROM Application_Leg AS app 
    INNER JOIN State AS state 
    ON app.State_Id = state.ID 
    WHERE (app.State_Id = 5 OR app.State_Id = 6 OR app.State_Id = 8) AND app.Organisation_Id=12 
    AND Leg_Number IN 
    (SELECT DISTINCT Leg_Number 
    from Application_Leg as al 
    INNER JOIN 
    Organisation as org 
    ON al.Organisation_Id = org.ID 
    WHERE al.ID=app.ID AND org.Approval_Required=1 AND Mode_Of_Transport=1)) 
    as pagedApplications 
    WHERE rowNum BETWEEN 0 AND (0 + 10) 

Когда удаляется внешний DISTINCT, порядок убывания прекрасен, но когда он включен, результаты не отображаются в порядке убывания.

ответ

0

Вы попробовали добавить заказ своим внешним выбором?

9

ORDER BY в статье ROW_NUMBER не гарантирует порядок набора результатов.

ROW_NUMBER обычно использует сортировку в плане запроса, что приводит к тому, что значения выдаются заранее.

Это побочный эффект, на который нельзя положиться.

DISTINCT использует Hash Match (Aggregate) который разбивает сортировку.

Добавить ORDER BY пункт в конце запроса:

SELECT DISTINCT (ID), State_Id, Name_Of_Trip, Date_Of_Travel, Creation_Date, Locking_Id, Applicant_Name, Reference_Number, State_Name 
FROM (
     SELECT app.ID, app.State_Id, app.Name_Of_Trip, app.Date_Of_Travel, 
       app.Creation_Date, app.Locking_Id, app.Applicant_Name, app.Reference_Number, 
       State.Name AS State_Name, ROW_NUMBER() OVER(ORDER BY Reference_Number DESC) as rowNum 
     FROM Application_Leg AS app 
     INNER JOIN 
       State AS state 
     ON  app.State_Id = state.ID 
     WHERE app.State_Id IN (5, 6, 8) 
       AND app.Organisation_Id = 12 
       AND Leg_Number IN 
       (
       SELECT Leg_Number 
       FROM Application_Leg as al 
       INNER JOIN 
         Organisation as org 
       ON  al.Organisation_Id = org.ID 
       WHERE al.ID = app.ID 
         AND org.Approval_Required = 1 
         AND Mode_Of_Transport = 1 
       ) 
     ) AS pagedApplications 
WHERE rowNum BETWEEN 0 AND (0 + 10) 
ORDER BY 
     ReferenceNumber DESC 

отметить также, что он не возвращает 10 различные результаты, он будет возвращать DISTINCT из первых 10 результатов.

Если вы хотите бывший, используйте:

SELECT DISTINCT TOP 10 ID, State_Id, Name_Of_Trip, Date_Of_Travel, Creation_Date, Locking_Id, Applicant_Name, Reference_Number, State_Name 
FROM (
     SELECT app.ID, app.State_Id, app.Name_Of_Trip, app.Date_Of_Travel, 
       app.Creation_Date, app.Locking_Id, app.Applicant_Name, app.Reference_Number, 
       State.Name AS State_Name 
     FROM Application_Leg AS app 
     INNER JOIN 
       State AS state 
     ON  app.State_Id = state.ID 
     WHERE app.State_Id IN (5, 6, 8) 
       AND app.Organisation_Id = 12 
       AND EXISTS 
       (
       SELECT Leg_Number 
       FROM Application_Leg AS al 
       INNER JOIN 
         Organisation as org 
       ON  al.Organisation_Id = org.ID 
       WHERE al.ID = app.ID 
         AND al.LegNumber = app.LegNumber 
         AND org.Approval_Required = 1 
         AND Mode_Of_Transport = 1 
       ) 
     ) AS pagedApplications 
ORDER BY 
     ReferenceNumber DESC 
+0

Это довольно интересно. – David