Sql 我如何才能不重复计算查询中的行和对象?

Sql 我如何才能不重复计算查询中的行和对象?,sql,sql-server,date,count,Sql,Sql Server,Date,Count,我希望统计一组人每月有一个请求的实例,但是我只想统计一次,而不是该人请求某件事情的次数。这是我的数据表的一个例子,所以这可能更有意义 Client Customer ID Request ID RequestStartDate RequestEndDate 1 A1 9991 03/04/19 07/03/19 1 A1 9992

我希望统计一组人每月有一个请求的实例,但是我只想统计一次,而不是该人请求某件事情的次数。这是我的数据表的一个例子,所以这可能更有意义

Client    Customer ID   Request ID   RequestStartDate   RequestEndDate
 1         A1              9991            03/04/19         07/03/19
 1         A1              9992            07/05/19         08/05/19
 1         A1              9993            08/09/19         10/01/19
有大约3万个结果,但我编写了一个查询,每月在请求时获取实例,这就是我得出的结论:

Select Distinct
CLient,
       (SELECT COUNT(*) from #Testdata21234 where '2019-07-01' BETWEEN dateadd(month, datediff(MONTH, 0, #testdata21234.RequestStartDate), 0) and dateadd(month, datediff(MONTH, 0, #testdata21234.BRequestEndDate), 0) AND CLient = g.Client) as 'July19',
    (SELECT COUNT(*) from #Testdata21234 where '2019-08-01' BETWEEN dateadd(month, datediff(MONTH, 0, #testdata21234.RequestStartDate), 0) and dateadd(month, datediff(MONTH, 0, #testdata21234.RequestEndDate), 0) AND CLient = g.Client) as 'August19',
    (SELECT COUNT(*) from #Testdata21234 where '2019-09-01' BETWEEN dateadd(month, datediff(MONTH, 0, #testdata21234.RequestStartDate), 0) and dateadd(month, datediff(MONTH, 0, #testdata21234.RequestEndDate), 0) AND CLient = g.Client) as 'September19'

FROM #testdata21234 g
group by client
如果使用上面的例子,我的结果就是这样

July19    August19     September19
  2           2             1
我希望我的输出得到以下结果:

July19    August19     September19
  1           1             1
本质上,我希望这只计算一次,因为尽管有多个请求,但它在同一个客户ID下,并且我不计算单独的实例,就在客户主动执行请求时

我希望这是有意义的,请,任何帮助将是伟大的

编辑:

为了进一步解释,让我们试试这个例子

Client   Customer ID   RequestID    RequestStartDate   RequestEndDate
1            A1          9991             03/03/19         07/03/19
1            A1          9992             07/05/19         08/05/19
1            A1          9993             08/09/19         10/01/19
1            A2          9994             07/02/19         07/10/19
1            A2          9995             07/15/19         08/06/19
1            A3          9996             02/01/19         07/01/19
1            A4          9997             08/05/19         08/16/19
1            A4          9998             08/30/19         09/01/19
对于上面的示例,我需要以下按月计数的结果

July19    August19    Septemeber19
4           3            2
我是基于clientID计算的,但是需要基于requestID进行过滤。我希望这更有意义,抱歉造成混淆。

您可以使用countdistinct并从根本上简化日期比较逻辑。我很确定你想要的客户与月份完全重叠,所以:

Select client,       
       (select count(*)
        from #Testdata21234 g2
        where g2.RequestStartDate  < '2019-08-01' and
              g2.RequestEndDate >= '2019-07-01'
       ) July19,
       (select count(*)
        from #Testdata21234 g2
        where g2.RequestStartDate  < '2019-09-01' and
              g2.RequestEndDate >= '2019-08-01'
       ) Aug19,
       (select count(*)
        from #Testdata21234 g2
        where g2.RequestStartDate  < '2019-10-01' and
              g2.RequestEndDate >= '2019-09-01'
       ) Sep19
from (select distinct client #testdata21234) g;

您可以多次访问同一个表,这可以通过使用条件聚合来简化。此外,您可能需要检查请求开始/结束是否与给定月份重叠。关于每个客户一次,可以使用DISTNCT:

Select client,       
       count(distinct CASE WHEN RequestEndDate >= '2019-07-01'
                       AND RequestStartDate  < '2019-08-01'
                      then "Customer ID" end) AS July19, -- don't know if this matches your logic, once per customer?
       count(distinct CASE WHEN RequestEndDate >= '2019-08-01' -- overlap calculation
                       AND RequestStartDate  < '2019-09-01'
                      then "Customer ID" end) AS Aug19,
       count(distinct CASE WHEN RequestEndDate >= '2019-09-01'
                       AND RequestStartDate  < '2019-10-01'
                      then "Customer ID" end) AS Sep19
from #testdata21234
group by client;

我认为每个月的硬编码不是很好的SQL逻辑,应该使用GROUPBY和format。因此,例如,如果您试图计算每个月启动的客户机数量,您应该执行以下操作:

SELECT 
    FORMAT(g."RequestStartDate",'MMMM yy') month_year,
    COUNT(DISTINCT g."Customer ID") count_clients
FROM #testdata21234 g
GROUP BY 1

现在,添加g.RequestEndDate和其他您想要的内容仍然有逻辑,但这是我建议的方向。

为什么第一个计算为7月,而第三个计算为9月?最后一次不应该是十月吗?我不清楚您是如何为每个请求分配月份的。使用GROUP BY的DISTINCT几乎总是多余的,通常意味着您的GROUP BY是错误的。在本例中,是前者。因此,这将每月的计数减少到“1”。过滤30k的结果,这是不对的。在我的例子中,我想这是可行的,但对于更大更复杂的样本量,这不起作用。这将每月的计数减少到“1”:如果客户和客户之间存在1-1关系,则是。您需要解释您的逻辑,请参见编辑。很抱歉给你带来了困惑。感谢您的帮助,到目前为止,您的编辑显示了my Select返回的结果,每个月的不同客户ID的数量。我得到了下面提到的相同问题,无论发生什么情况,每月统计一个。请参见编辑。@Ziegler199。只需使用count*。正如最初的答案试图暗示的那样,countdistinct似乎并不合适。