排名函数和连接

Ranking functions and Joins

我有以下 tables.

Order_det

Ord_num item_code Unit_sales_price
1111 1 50
1111 2 40
1111 3 30
1111 4 20
1111 5 10
2222 3 30

Pick_det

Ord_num Shipment_num Item_code Qty_to_pick Qty_picked
1111 1 1 100 100
1111 2 1 100 100
1111 3 2 100 100
2222 3 3 200 200

我想要table如下,

Ord_num Shipment_num Item_code Qty_to_pick Qty_picked Unit_sales_price Total_price (Unit_sales_price*Qty_picked)
1111 3 2 100 100 40 4000
2222 3 3 200 200 30 6000

在这个社区的帮助下,我找到了一个非常相似的答案,即, Link 到那个答案,

    select *
from
(
  select t1.*, max(shipment_num) over (partition by ord_num) as orders_max_ship_num
  from pick_det t1
) with_max
where shipment_num = orders_max_ship_num
order by ord_num, item_code;

我的问题是, 我在哪里加入 Order_det table 以获得 Unit_sales_price 值到已经从 pick_det table?[=15 检索到的最大 shipment_num 行=]

您可以简单地基于您的查询:

with s as
(
  select *
  from
  (
    select t1.*, max(shipment_num) over (partition by ord_num) as orders_max_ship_num
    from pick_det t1
  ) with_max
  where shipment_num = orders_max_ship_num
)
select
  s.ord_num, s.shipment_num, s.item_code, s.qty_to_pick, s.qty_picked,
  od.unit_sales_price, od.unit_sales_price * s.qty_picked as total_price
from s
join order_det od on od.ord_num = s.ord_num and od.item_code = s.item_code
order by s.ord_num, s.item_code;

或者您立即应用连接:

select
  s.ord_num, s.shipment_num, s.item_code, s.qty_to_pick, s.qty_picked,
  od.unit_sales_price, od.unit_sales_price * s.qty_picked as total_price
from
(
  select t1.*, max(shipment_num) over (partition by ord_num) as orders_max_ship_num
  from pick_det t1
) s
join order_det od on od.ord_num = s.ord_num and od.item_code = s.item_code
where s.shipment_num = s.orders_max_ship_num
order by s.ord_num, s.item_code;

我迟到了,因为我输入了所有内容并确保 运行 正确

if OBJECT_ID('tempdb..#Order_det') IS NOT NULL DROP TABLE #Order_det;
if OBJECT_ID('tempdb..#Pick_det') IS NOT NULL DROP TABLE #Pick_det;

CREATE TABLE #Order_det (Ord_num INT, item_code INT, Unit_sales_price INT);
CREATE TABLE #Pick_det(Ord_num INT, Shipment_num INT, Item_code INT, Qty_to_pick INT, Qty_picked INT);

INSERT INTO #Order_det (Ord_num, item_code, Unit_sales_price)
VALUES
(1111,  1,  50),
(1111,  2,  40),
(1111,  3,  30),
(1111,  4,  20),
(1111,  5,  10),
(2222,  3,  30)

INSERT INTO #Pick_det (Ord_num, Shipment_num, Item_code, Qty_to_pick, Qty_picked)
VALUES
(1111,  1,  1,  100,    100),
(1111,  2,  1,  100,    100),
(1111,  3,  2,  100,    100),
(2222,  3,  3,  200,    200)

SELECT
    OrderDet.Ord_num
    , PickList.Shipment_Num
    , OrderDet.Item_code
    , PickList.Qty_to_pick 
    , PickList.Qty_picked 
    , OrderDet.Unit_sales_price
    , OrderDet.Unit_sales_price * PickList.Qty_picked AS Total_price
FROM
    (
        SELECT 
            Ord_num
            , MAX(Shipment_num) OVER (PARTITION BY ord_num) AS MaxShipment_Num--
            , Shipment_num
            , Item_code
            , Qty_to_pick 
            , Qty_picked 
        FROM #Pick_det
    ) AS PickList 
    INNER JOIN  #Order_det AS OrderDet
        ON OrderDet.Ord_num = PickList.Ord_num 
        AND OrderDet.item_code = PickList.Item_code
        and PickList.Shipment_num = PickList.MaxShipment_Num

您可以使用的另一种简单技术是应用分析函数 - Dense_Rank 这是一个 window 函数,它为结果集的分区内的每一行分配一个等级

我正在尝试按 shipment_num 降序排列,然后仅加入公共列。我也用过 CTE 和子查询:

With temp AS(Select * from (SELECT a.*, dense_rank() OVER (PARTITION BY ord_num order by shipment_num desc) rnk
from Pick_det a) t where rnk = 1)

Select temp.Ord_num, temp.Shipment_num, temp.item_code, temp.Qty_to_pick, temp.Qty_picked,
temp.qty_to_pick * Order_det.Unit_sales_price total_price
from temp  JOIN Order_det on temp.ord_num = Order_det.ord_num
AND temp.item_code = Order_det.item_code;

您的子查询看起来像这样:

Select temp.Ord_num, temp.Shipment_num, temp.Item_code, temp.Qty_to_Pick, temp.Qty_picked,
temp.qty_to_pick * Order_det.Unit_sales_price total_price
from 
(SELECT a.*, dense_rank() OVER (PARTITION BY ord_num order by shipment_num desc) rnk
from Pick_det a) temp INNER JOIN Order_det on temp.ord_num = Order_det.ord_num
AND temp.item_code = Order_det.item_code
AND temp.rnk = 1;

如果你想了解dense_rank函数,这里是link

这是SQL Fiddle