根据条件减去行
Subtracting rows based on condition
假设我有一个 table 看起来像这样:
OrderNumber OrderType
1 D
1 D
1 R
2 D
2 R
3 D
3 D
3 D
3 R
3 R
结果应该是:
OrderNumber OrderType
1 D
3 D
在这里,R 表示从订单中删除一行。我们在第一个示例中看到我们有 2 个 D 和 1 个 R,因此我们删除一个 D 并用 1 个 D 替换。在 SQL 中有没有办法做到这一点?
您可以使用window功能。这是 sqlite 语法,但 mysql 应该相当接近。
select A.OrderNumber,A.OrderType
from (select OrderNumber,OrderType,row_number() over(partition by OrderNumber) as RN
from b where OrderType='D') A
left join
(select sum(case when OrderType='R' then 1 else 0 end) as cnt,OrderNumber
from b group by OrderNumber) B
on A.OrderNumber=B.OrderNumber
where A.rn>B.cnt;
如果你的mysql版本支持cte和window函数,我们可以尝试使用ROW_NUMBER
window函数为每个OrderNumber
制作行号OrderType
然后使用EXISTS
子查询判断OrderType = D
行号需要大于来自R
.
的最大行号
with cte as (
SELECT *,
ROW_NUMBER() OVER(PARTITION BY OrderNumber,OrderType) rn,
COUNT(*) OVER(PARTITION BY OrderNumber,OrderType) cnt
FROM T
)
SELECT c1.OrderNumber,
c1.OrderType
FROM cte c1
WHERE EXISTS (
SELECT 1
FROM cte c2
WHERE c1.OrderNumber = c2.OrderNumber
AND c2.OrderType = 'R'
AND c1.rn > c2.cnt
)
AND c1.OrderType = 'D'
假设我有一个 table 看起来像这样:
OrderNumber OrderType
1 D
1 D
1 R
2 D
2 R
3 D
3 D
3 D
3 R
3 R
结果应该是:
OrderNumber OrderType
1 D
3 D
在这里,R 表示从订单中删除一行。我们在第一个示例中看到我们有 2 个 D 和 1 个 R,因此我们删除一个 D 并用 1 个 D 替换。在 SQL 中有没有办法做到这一点?
您可以使用window功能。这是 sqlite 语法,但 mysql 应该相当接近。
select A.OrderNumber,A.OrderType
from (select OrderNumber,OrderType,row_number() over(partition by OrderNumber) as RN
from b where OrderType='D') A
left join
(select sum(case when OrderType='R' then 1 else 0 end) as cnt,OrderNumber
from b group by OrderNumber) B
on A.OrderNumber=B.OrderNumber
where A.rn>B.cnt;
如果你的mysql版本支持cte和window函数,我们可以尝试使用ROW_NUMBER
window函数为每个OrderNumber
制作行号OrderType
然后使用EXISTS
子查询判断OrderType = D
行号需要大于来自R
.
with cte as (
SELECT *,
ROW_NUMBER() OVER(PARTITION BY OrderNumber,OrderType) rn,
COUNT(*) OVER(PARTITION BY OrderNumber,OrderType) cnt
FROM T
)
SELECT c1.OrderNumber,
c1.OrderType
FROM cte c1
WHERE EXISTS (
SELECT 1
FROM cte c2
WHERE c1.OrderNumber = c2.OrderNumber
AND c2.OrderType = 'R'
AND c1.rn > c2.cnt
)
AND c1.OrderType = 'D'