我需要在订单数量达到特定值的第一个日期对客户进行细分。
例如,我们有一个订单表ID, ClientID, Date
1, 1, 1/1/2011
2, 1 2/1/2011
3, 1 3/1/2011
4, 1 4/1/2011
我想获得至少有3个订单的所有客户,并在达到3个订单时获得日期字段。 在我的例子中,查询将显示:
ClientID: 1, Date: 3/1/2011
(因为2011年3月1日,客户达到3个订单)
我该怎么做?
由于
更新
我正在寻找你的解决方案(非常感谢!)但是我也需要用SUM做同样的事情(假设上面的表有一个名为amount的字段,我想分割客户端并得到客户订单达到100美元的第一个日期) 我虽然解决方案将帮助我理解逻辑并轻松将计数转换为求和并进行新的查询但我在这里有点丢失..任何想法?
答案 0 :(得分:1)
我会按照以下方式做点什么:
DECLARE @ClientId int, @RowNumber int
SELECT @ClientId = 1, @RowNumber = 3
SELECT ClientId, [Date]
FROM
(
SELECT TOP (@RowNumber) ClientId, [Date], ROW_NUMBER() OVER(ORDER BY ID) AS RowNumber
FROM Test
WHERE ClientId = @ClientId
) D
WHERE RowNumber = @RowNumber
您可以将客户端ID和行数作为参数处理,以用于您最终使用的任何过程。
答案 1 :(得分:0)
这样的事情:
SELECT clientid, date
FROM (
SELECT id,
clientid,
row_number() over (partition by clientid order by date) as running_count,
date
FROM orders
) t
WHERE running_count = 3
修改强>
由于SQL Server中对窗口函数的不完全支持,我的解决方案无法扩展到涵盖sum()要求。
但为了完整起见,我尽可能地举了一个例子:
SELECT clientid, date
FROM (
SELECT id,
clientid,
row_number() over (partition by clientid order by date) as running_count,
sum(amount) over (partition by clientid order by date) as running_sum,
date
FROM orders
) t
WHERE running_sum = 100
OR running_count = 3
但是再次:这将 在SQL Server中工作
答案 2 :(得分:0)
这将选择所有具有3个订单且具有第3个订单日期的客户。
--DECLARE @clientID INT
--SET @clientID = 1
DECLARE @count INT
SET @count = 3 -- Set the count to this variable.
SELECT ClientID, [Date]
FROM [yourtable] a
WHERE COALESCE( (SELECT COUNT(*)
FROM [yourtable] b
WHERE b.[Date] < a.[Date] and b.ClientID = a.ClientID ),0) = @count - 1
ORDER BY ClientID
选择具有第三个订单日期的单个客户,其中可以使用附加条件进行修改。
AND a.ClientID = @clientID
基于问题更新的更新 - 这个查询几乎没有来自count woud的修改,可以为您提供运行总和选择。此处列出了running sum的更多技术。
DECLARE @sum INT
SET @count = 100 -- Set the amount to this variable.
SELECT ClientID, [Date]
FROM [yourtable] a
WHERE ( a.Amount + COALESCE( (SELECT SUM(b.Amount)
FROM [yourtable] b
WHERE b.[Date] < a.[Date] and b.ClientID = a.ClientID ),0) ) = @sum
ORDER BY ClientID
答案 3 :(得分:0)
测试表和测试数据
declare @T table (ID int, ClientID int, [Date] datetime, Amount money)
insert into @T values
(1, 1, '1/1/2011', 10),
(2, 1, '2/1/2011', 20),
(3, 1, '3/1/2011', 30),
(4, 1, '4/1/2011', 40),
(5, 2, '1/1/2011', 10),
(6, 2, '2/1/2011', 20),
(7, 2, '3/1/2011', 30)
获得第三排并不是那么难。这与提供的a_horse_with_no_name解决方案相同。
declare @Row int = 3
;with cte as
(
select *,
row_number() over(partition by ClientID order by [Date]) as rn
from @T
)
select *
from cte
where rn = @Row
要在运行总和超过某个值时获取该行有点困难。这是一个循环版本,使用临时表来更新运行总和。
declare @sum money = 30
select *, cast(0 as money) as Running
into #T
from @T
declare @rn int = 1
;with cte as
(
select
Running,
Amount,
row_number() over(partition by ClientID order by [Date]) as rn
from #T
)
update cte set
Running = Amount
where
rn = @rn
while @@rowcount >= 1
begin
set @rn = @rn + 1
;with cte as
(
select
Running,
Amount,
row_number() over(partition by ClientID order by [Date]) as rn
from #T
)
update cte set
Running = Running + Amount
where rn = @rn
end
;with cte as
(
select *,
row_number() over(partition by ClientID order by [Date]) as rn
from #T
where Running >= @sum
)
select *
from cte
where rn = 1
drop table #T