当count达到一个值时,获取第一个字段

问题描述

| 我需要在客户的订单数达到特定值的第一天对客户进行细分。 例如,我们有一个订单表
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