我有2个具有一对多关系的SQL SERVER表
Table : Orders
---------------
BILL_NO QUANTITY
100 1
101 2
Table : Mobility
----------------
MOBILITY_UID BILL_NO DATE CURRENT_LOCATION
1 101 20/07/18 1_NO-SHOP
2 101 21/07/18 2_NO_SHOP
3 102 21/07/18 WORKSHOP
现在我需要一个查询来根据BILL的上次位置更新获取哪个位置有多少订单(例如2_NO_SHOP是BILL no 101的最后一个位置,因为它最后一次使用MOBILITY_UID = 2进行了更新)
预期结果:
CURRENT_LOCATION QUANTITY
1_NO_SHOP 0
2_NO_SHOP 2
WORKSHOP 1
答案 0 :(得分:1)
outer apply
按位置获取数量-但不获取零数量。
select m.current_location, o.quantity
from orders o outer apply
(select top (1) m.*
from mobility m
where m.bill_no = o.bill_no
order by date desc
) m;
我将建议:
select l.location, coalesce(mo.quantity, 0) as quantity
from (select distinct current_location as location from mobility) l left join
(select m.current_location, o.quantity
from orders o outer apply
(select top (1) m.*
from mobility m
where m.bill_no = o.bill_no
order by date desc
) m
) mo
on mo.current_location = l.location
另一种方法使用row_number()
:
select m.current_location,
max(case when seqnum = 1 then o.quantity else 0 end) as quantity
from (select m.*, row_number() over (partition by m.bill_no order by m.date desc) as seqnum
from mobility m
order by date desc
) m left join
orders o
on m.bill_no = o.bill_no
答案 1 :(得分:0)
也许这可以解决问题?
SELECT
CURRENT_LOCATION
, quantity
FROM (
SELECT
M.CURRENT_LOCATION
, CASE WHEN Bill_DATE = MAX(M.Bill_DATE) OVER(PARTITION BY M.BILL_NO ORDER BY M.Bill_DATE DESC) THEN O.quantity ELSE 0 END quantity
, ROW_NUMBER() OVER(PARTITION BY M.BILL_NO ORDER BY M.Bill_DATE DESC) RN
FROM Mobility M
LEFT JOIN Orders O ON O.BILL_NO = M.BILL_NO
) D
ORDER BY CURRENT_LOCATION
答案 2 :(得分:0)
我做了一个函数
IF OBJECT_ID (N'dbo.getCurrentLocation', N'FN') IS NOT NULL
DROP FUNCTION getCurrentLocation;
GO
CREATE FUNCTION dbo.getCurrentLocation(@BILLNO VARCHAR(10))
RETURNS VARCHAR(20)
AS
BEGIN
DECLARE @ret VARCHAR(20);
SELECT @ret = (SELECT TOP 1 CURRENT_LOCATION
FROM MOBILITY OM
WHERE OM.BILL_NO = @BILLNO
ORDER BY MOBILITY_UID DESC)
IF (@ret IS NULL)
SET @ret = '';
RETURN @ret;
END;
然后使用汇总查询
SELECT DBO.getCurrentLocation(od.BILL_NO) AS LOCATION
,sum(OD.QUANTITY) FROM ORDERS OD
where DBO.getCurrentLocation(od.BILL_NO) <> ''
group by DBO.getCurrentLocation(od.BILL_NO)