这是我如何实现的......告诉我我的逻辑是否合理:
/****Create Sample Data*****/
-->Member table
IF exists (SELECT 1 from dbo.sysobjects WHERE name = 'Member')
DROP TABLE Member
GO
CREATE TABLE Member (membername VARCHAR(50), memberkey INT)
GO
INSERT INTO Member VALUES
('mbr1',702),
('mbr2',1382),
('mbr3',1389),
('mbr4',1390),
('mbr5',1391),
('mbr6',1392),
('mbr7',1393),
('mbr8',1394),
('mbr9',1395),
('mbr10',1396),
('mbr11',1397),
('mbr12',1401),
('mbr13',1402),
('mbr14',1404),
('mbr15',1405),
('mbr16',1406),
('mbr17',1516),
('mbr18',1111)-->Should NOT show up in query
GO
-->Items table
IF exists (SELECT 1 from dbo.sysobjects WHERE name = 'Items')
DROP TABLE Items
GO
CREATE TABLE Items (itemname VARCHAR(50), itemkey INT)
GO
INSERT INTO Items VALUES
('A',1),
('B',2),
('C',3),
('D',4)
GO
-->UOM table
IF exists (SELECT 1 from dbo.sysobjects WHERE name = 'UOM')
DROP TABLE UOM
GO
CREATE TABLE UOM (uomname VARCHAR(50), uomkey INT)
GO
INSERT INTO UOM VALUES ('QTY', 1)
GO
-->Fact table
IF exists (SELECT 1 from dbo.sysobjects WHERE name = 'Fact')
DROP TABLE Fact
GO
CREATE TABLE Fact (memberkey INT, itemkey INT, uomkey INT, purchaseamount decimal(18,2), quantity INT, purchasedate date)
GO
INSERT INTO Fact VALUES
(702, 1, 1, 1.11, 2, '1/3/2012'),-->Should show up in query
(1382, 1, 1, 1.12, 3, '1/4/2013'),-->Should NOT show up in query
(1382, 1, 1, 1.14, 2, '7/5/2013'),-->Should show up in query
(1404, 1, 1, 1.21, 2, '1/7/2012'),-->Should show up in query
(1401, 2, 1, 3.01, 1, '4/2/2013'),-->Should NOT show up in query
(1111, 3, 1, 6.92, 1, '12/12/2012'),-->Should NOT show up in query
(702, 3, 1, 5.01, 2, '4/1/2011'),-->Should show up in query
(1401, 3, 1, 4.01, 1, '6/5/2012'),-->Should show up in query
(1397, 4, 1, 5.45, 1, '7/4/2013'),-->Should NOT show up in query
(1397, 4, 1, 5.22, 3, '3/15/2011')-->Should NOT show up in query
GO
/*****Code to get results*****/
BEGIN
-->Members to Filter On
DECLARE @MemberKeys AS VARCHAR(max)
SET @MemberKeys = '702,1382,1389,1390,1391,1392,1393,1394,1395,1396,1397,1401,1402,1404,1405,1406,1516,1844';
-->Parse out comma delimited VALUES into a table variable
DECLARE @Member TABLE
(
memberkey INT
)
DECLARE @spot SMALLINT, @str VARCHAR(max), @sql VARCHAR(max)
WHILE @MemberKeys <> ''
BEGIN
SET @spot = CHARINDEX(',', @MemberKeys)
IF @spot>0
BEGIN
SET @str = LEFT(@MemberKeys, @spot-1)
SET @MemberKeys = RIGHT(@MemberKeys, LEN(@MemberKeys)-@spot)
END
ELSE
BEGIN
SET @str = @MemberKeys
SET @MemberKeys = ''
END
INSERT INTO @Member VALUES(CONVERT(VARCHAR(100),@str))
END
END;
-->Display Results
WITH staged(memberkey, membername, itemname ,itemkey, uomname, uomkey, purchaseamount, quantity, price, purchasedate, noitems )
AS
(
SELECT
m.memberkey
,m.membername
,i.itemname
,i.itemkey
,u.uomname
,u.uomkey
,f.purchaseamount
,f.quantity
,f.purchaseamount/f.quantity as price
,f.purchasedate
,COUNT(m.memberkey) OVER(PARTITION BY i.itemkey )-COUNT(m.memberkey) OVER(PARTITION BY convert(VARCHAR,m.memberkey)+convert(VARCHAR,i.itemkey) ) as noitems
FROM
Fact f
JOIN Member m ON m.memberkey = f.memberkey
JOIN Items i ON i.itemkey = f.itemkey
JOIN UOM u ON u.uomkey= f.uomkey
WHERE
EXISTS(SELECT 1 FROM @Member m2 WHERE m.memberkey=m2.memberkey)
)
SELECT
memberkey,
membername,
itemname ,
itemkey,
uomname,
uomkey,
sum(purchaseamount) as purchaseamount ,
sum(quantity) as quantity ,
sum(price) as price,
max(purchasedate) as purchasedate
FROM
staged st
WHERE
noitems>0
and exists(
select memberkey,
itemkey ,
uomkey,
max(purchasedate) as maxdate
from staged st2
where st.memberkey=st2.memberkey
and st.itemkey=st2.itemkey
and st.uomkey=st2.uomkey
group by
memberkey,
itemkey ,
uomkey
having st.purchasedate=max(st2.purchasedate)
)
GROUP BY
memberkey
,membername
,itemname
,uomname
, itemkey
, uomkey
ORDER BY
itemname
,memberkey;