SQL Server - 在复杂查询中使用Over / Partition By

时间:2017-05-31 16:06:02

标签: sql-server sql-server-2012

我们有许多复杂的查询涉及很多列和连接(请参阅下面的示例),这些列和连接都是作为视图实现的。

在某些情况下,这些查询会返回重复的行,然后必须通过使用应用程序以编程方式删除这些行。因此,我们希望增强SQL查询以消除重复,并加快检索过程。

我知道我可以使用OVER / PARTITION BY逻辑来执行此操作,但我不确定如何修改查询以获取有效的语法。

以下是一个例子:

SELECT
    Main.MfgOrder.OrderNumber,
    Main.MfgOrder.DesignBOMID,
    Main.Design_Plant.PlantID,
    Main.MfgOrder_Operation.OrderOpID,
    Main.MfgOrder_Operation.DesignOpID,
    Main.MfgOrder_Operation.OpSeq, 
    Main.MfgOrder_Operation.Description,
    Main.MfgOrder_Operation.CompletionStatus,
    Main.MfgOrder__Shift.OrderShiftID,
    Main.MfgOrder__Shift.WorkCenterMachineID,
    Main.MfgOrder___Event.OrderEventID,
    Main.MfgOrder____Reel.OrderReelID,
    Main.MfgOrder____Reel.ReelNumber,
    Main.MfgOrder____Reel.Location, 
    Main.MfgOrder____Reel.Test_Status AS Test_Status_Reel,
    Main.MfgOrder____Reel.Test_Disposition AS Test_Disposition_Reel,
    Main.MfgOrder____Reel.LabReleased,
    Main.MfgOrder____Reel.ShipReelsBypassSet,
    Main.MfgOrder_____Length.OrderLengthID,
    Main.MfgOrder_____Length.LengthType, 
    Main.MfgOrder_____Length.LocationOnReel,
    Main.MfgOrder_____Length.LocationOnLength, 
    Main.MfgOrder_____Length.TrialNumber,
    Main.MfgOrder_____Length.SampleNumber, 
    Main.MfgOrder_____Length.PrintNumber,
    Main.MfgOrder_____Length.Test_Status AS Test_Status_Length,
    Main.MfgOrder_____Length.Test_Category,
    Main.MfgOrder_____Length.Test_Disposition AS Test_Disposition_Length,
    Main.MfgOrder_____Length.SampleSubmittedBy,
    Main.MfgOrder_____Length.SampleSubmittedDate,
    Main.MfgOrder_____Length.BypassTesting,
    Main.MfgOrder_____Length_OperatorQty.Sample1Destination,
    Main.MfgOrder_____Length_OperatorQty.Sample2Destination,
    Main.MfgOrder_____Length_OperatorQty.Sample3Destination,
    Main.MfgOrder______Component.OrderComponentID,
    Main.MfgOrder______Component.DesignComponentID,
    Main.MfgOrder______Component.ItemNo, 
    Main.MfgOrder_______Test.LabTestID,
    Main.MfgOrder_______Test.OrderTestID,
    Main.MfgOrder_______Test.TestComplete,
    Main.MfgOrder_______Test.TestStatus,
    Main.MfgOrder________Marker2.OrderMarkerID,
    Master.Color.ColorName,
    Master.LabTest.ExcludeFromPassFail,
    CASE 
       WHEN Main.Design_Component.Component_Label IS NULL 
          THEN 'Unknown' 
          ELSE Main.Design_Component.Component_Label 
    END AS Component_Label
FROM
    Main.MfgOrder
INNER JOIN 
    Main.Design__BOM ON Main.MfgOrder.DesignBOMID = Main.Design__BOM.DesignBOMID
INNER JOIN 
    Main.Design_Plant ON Main.Design__BOM.DesignPlantID = Main.Design_Plant.DesignPlantID
INNER JOIN 
    Main.MfgOrder_Operation ON Main.MfgOrder.OrderNumber = Main.MfgOrder_Operation.OrderNumber
INNER JOIN 
    Main.MfgOrder__Shift ON Main.MfgOrder_Operation.OrderOpID = Main.MfgOrder__Shift.OrderOpID
INNER JOIN 
    Main.MfgOrder___Event ON Main.MfgOrder__Shift.OrderShiftID = Main.MfgOrder___Event.OrderShiftID
INNER JOIN 
    Main.MfgOrder____Reel ON Main.MfgOrder___Event.OrderEventID = Main.MfgOrder____Reel.OrderEventID
INNER JOIN 
    Main.MfgOrder_____Length ON Main.MfgOrder____Reel.OrderReelID = Main.MfgOrder_____Length.OrderReelID
LEFT OUTER JOIN 
   Main.MfgOrder______Component ON Main.MfgOrder_____Length.OrderLengthID = Main.MfgOrder______Component.OrderLengthID
LEFT OUTER JOIN 
    Main.MfgOrder_______Test ON Main.MfgOrder______Component.OrderComponentID = Main.MfgOrder_______Test.OrderComponentID
LEFT OUTER JOIN 
    Main.MfgOrder________Marker2 ON Main.MfgOrder_______Test.OrderTestID = Main.MfgOrder________Marker2.OrderTestID
LEFT OUTER JOIN 
    Main.Design_Component ON Main.MfgOrder______Component.DesignComponentID = Main.Design_Component.DesignComponentID
LEFT OUTER JOIN 
    Master.Color ON Main.MfgOrder______Component.TapeColorID = Master.Color.ColorNumber
LEFT OUTER JOIN 
    Master.LabTest ON Main.MfgOrder_______Test.LabTestID = Master.LabTest.LabTestID
LEFT OUTER JOIN 
    Main.MfgOrder_____Length_OperatorQty ON Main.MfgOrder______Component.OrderLengthID = Main.MfgOrder_____Length_OperatorQty.OrderLengthID

2 个答案:

答案 0 :(得分:1)

你可以使用如下的row_number:如果你需要添加你相应添加的其他列,下面的查询将不会仅在OrderNumber上选择重复

Select * from (
    Select 
         RowN = Row_Number() over( partition by Main.MfgOrder.OrderNumber order by Main.MfgOrder.OrderNumber),
         --- All your select columns and all your query with joins
  ) a
  Where a.RowN = 1

答案 1 :(得分:0)

整行是否完全重复?如果是,则只需添加DISTINCT

SELECT DISTINCT 
    ...
FROM
    ...

如果您获得重复的行,其中大多数列相同但某些列不同,则GROUP BY列相同,并选择MIN(column_name)作为导致额外行显示的列。