我做了以下假设:
-
您使用的是SQL Server 2005或更高版本。
-
somekey、objectid、zorder是唯一的。
其他注释:
-
我没有优化查询-我只是试图得到正确的结果。
-
我只在你的测试数据上测试过。
考虑到这一点,你可以尝试这样的方法:
WITH Bars AS (
SELECT
T1.SomeKey,
T1.ObjectID,
T1.ZOrder,
SUM(T2.PercentOfBar) - T1.PercentOfBar AS PercentStart,
SUM(T2.PercentOfBar) AS PercentEnd
FROM Table1 T1
JOIN Table1 T2
ON T1.SomeKey = T2.SomeKey
AND T1.ObjectID = T2.ObjectID
AND T1.ZOrder >= T2.ZOrder
GROUP BY T1.SomeKey, T1.ObjectID, T1.PercentOfBar, T1.ZOrder),
Boundaries AS (
SELECT P, ROW_NUMBER() OVER (ORDER BY P) AS rn
FROM (
SELECT DISTINCT PercentStart AS P FROM Bars
UNION
SELECT DISTINCT PercentEnd FROM Bars
) T1),
Intervals AS (
SELECT B1.P AS PercentStart, B2.P AS PercentEnd
FROM Boundaries B1
JOIN Boundaries B2
ON B1.rn + 1 = B2.rn),
Bits AS (
SELECT
SomeKey,
ObjectId,
ZOrder,
Intervals.PercentStart,
Intervals.PercentEnd
FROM Intervals
JOIN Bars
ON Bars.PercentStart <= Intervals.PercentStart
AND Bars.PercentEnd >= Intervals.PercentEnd),
LowestZOrder AS (
SELECT SomeKey, PercentStart, MIN(ZOrder) AS ZOrder
FROM Bits
GROUP BY SomeKey, PercentStart),
LowestBits AS (
SELECT Bits.*
FROM Bits
JOIN LowestZOrder
ON Bits.SomeKey = LowestZOrder.SomeKey
AND Bits.PercentStart = LowestZOrder.PercentStart
AND Bits.ZOrder = LowestZOrder.ZOrder)
SELECT
SomeKey,
MAX(PercentEnd) - MIN(PercentStart) AS PercentOfBar,
ZOrder
FROM LowestBits
GROUP BY SomeKey, ObjectID, ZOrder
ORDER BY SomeKey, ObjectID, MIN(PercentStart) DESC
结果:
SomeKey PercentOfBar ZOrder
X 50 5
X 20 4
X 30 3
Y 100 6
Z 50 2
Z 50 5
测试数据:
CREATE TABLE Table1 (SomeKey NVARCHAR(100) NOT NULL, ObjectID NVARCHAR(100) NOT NULL, PercentOfBar INT NOT NULL, ZOrder INT NOT NULL);
INSERT INTO Table1 (SomeKey, ObjectID, PercentOfBar, ZOrder) VALUES
('X', 'A', 100, 6),
('X', 'B', 50, 5),
('X', 'B', 50, 4),
('X', 'C', 30, 3),
('X', 'C', 70, 6),
('Y', 'A', 100, 6),
('Z', 'B', 50, 2),
('Z', 'B', 50, 6),
('Z', 'C', 100, 5);