问题描述
|
我需要在客户的订单数达到特定值的第一天对客户进行细分。
例如,我们有一个订单表
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做同样的事情(可以说,上表中的字段称为“金额”,我想细分客户并获得第一个约会)客户订单达到$ 100)
尽管这些解决方案将帮助我理解逻辑,并轻松将计数转换为求和并进行新的查询,但是我在这里迷失了一点。
解决方法
这将选择所有具有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
基于问题更新的更新-该查询在计数上几乎没有修改,可以为您提供连续的总和选择。此处列出了更多用于求和的技巧。
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
,我会按照以下方式做一些事情:
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和行数作为参数,以使用最终使用的任何过程。
,像这样:
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,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中将不起作用
,测试表和测试数据
declare @T table (ID int,ClientID int,[Date] datetime,Amount money)
insert into @T values
(1,1,\'1/1/2011\',10),(2,\'2/1/2011\',20),(3,\'3/1/2011\',30),(4,\'4/1/2011\',40),(5,2,(6,(7,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,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