2016-04-15 14 views
0

私は、週ごとに最も大きな注文の情報を返すクエリを取得しようとしています。SQL Server 2012で毎週最大レコードを取得するにはどうすればよいですか?

私の非常に基本的な考え方は次のようなものです:

select 
    datepart(ww, order_date), order_id, order_revenue, order_margin 
from 
    orders 
where 
    order_date >= 1/1/2016 
    and order_id in (select max order for each week) 

基本的に私はちょうど各週の最大の順序マージンレコードの週番号、注文ID、注文の収益、注文マージンをしたいです。

答えて

2

あなたが「窓関数」
https://www.simple-talk.com/sql/learn-sql-server/window-functions-in-sql-server/

select * 
from 
(select datepart(ww, order_date), order_date, order_id, order_revenue, order_margin 
     , row_number() over (partition by datepart(ww, order_date) order by order_margin desc) as rn 
    from orders 
    where order_date >= 1/1/2016 
) tt 
where tt.rn = 1 
order by order_date desc 

を使用する必要があると私はあなたが単一引用符に日付これは少し異なる方法で

0

が必要だと思います。それはもっと多くの詳細がありますが、それはAdventureWorksで実行するように設計されているためです(どのバージョンをどのように使用するかわからないため)。

USE AdventureWorks 

;WITH OrderDetails 
    AS (
     SELECT soh.SalesOrderID, CAST(soh.OrderDate AS DATE) AS OrderDate, 
      SUM(sod.OrderQty * (sod.UnitPrice - pch.StandardCost)) AS OrderMargin 
      FROM Sales.SalesOrderHeader soh 
       LEFT JOIN Sales.SalesOrderDetail sod 
        ON soh.SalesOrderID = sod.SalesOrderID 
       LEFT JOIN Production.ProductCostHistory pch 
        ON sod.ProductID = pch.ProductID 
      WHERE soh.OrderDate >= pch.StartDate AND soh.OrderDate <= pch.EndDate 
      GROUP BY soh.SalesOrderID, soh.OrderDate 
     ), 

MaxOrder 
    AS (
     SELECT DATEPART(yy,OrderDate) AS Year, DATEPART(ww,OrderDate) AS Week, 
      MAX(OrderMargin) AS MaxOrderMargin 
      FROM OrderDetails 
      GROUP BY DATEPART(yy,OrderDate), DATEPART(ww,OrderDate) 
     ) 

SELECT mo.Year, mo.Week, od.SalesOrderID, '$'+FORMAT(mo.MaxOrderMargin,'#,0.00') AS OrderMargin 
    FROM MaxOrder mo 
     INNER JOIN OrderDetails od 
      ON mo.MaxOrderMargin = od.OrderMargin 
     WHERE DATEPART(yy,od.OrderDate) = mo.Year AND DATEPART(ww,od.OrderDate) = mo.Week 
    ORDER BY Year, Week   

これは少しだけある点で、前の例以上の機能を向上させた、そしてそれは余裕をもってすべての注文が含まれますので、それが複数ある場合でも、です。ただし、これはROW_NUMBER()の代わりにRANK()を使用して実現できることに注意してください。 CTEを使用してここに表示する:

USE AdventureWorks 

;WITH OrderDetails 
    AS (
     SELECT soh.SalesOrderID, CAST(soh.OrderDate AS DATE) AS OrderDate, 
      SUM(sod.OrderQty * (sod.UnitPrice - pch.StandardCost)) AS OrderMargin 
      FROM Sales.SalesOrderHeader soh 
       LEFT JOIN Sales.SalesOrderDetail sod 
        ON soh.SalesOrderID = sod.SalesOrderID 
       LEFT JOIN Production.ProductCostHistory pch 
        ON sod.ProductID = pch.ProductID 
      WHERE soh.OrderDate >= pch.StartDate AND soh.OrderDate <= pch.EndDate 
      GROUP BY soh.SalesOrderID, soh.OrderDate 
     ), 

OrderRank 
    AS (
     SELECT DATEPART(yy,OrderDate) AS Year, DATEPART(ww,OrderDate) AS Week, 
      SalesOrderID, '$'+FORMAT(OrderMargin,'#,0.00') AS OrderMargin, 
      RANK() OVER (PARTITION BY DATEPART(yy,OrderDate), DATEPART(ww,OrderDate) ORDER BY OrderMargin DESC) AS MRank 
      FROM OrderDetails 
     ), 

MRank 
    AS (
     SELECT Year, Week, SalesOrderID, OrderMargin 
      FROM OrderRank 
       WHERE MRank = 1 
     ) 

SELECT * FROM MRank 
関連する問題