【问题标题】:SQL count date rangeSQL 计数日期范围
【发布时间】:2011-11-28 14:12:26
【问题描述】:

我正在尝试查询我的 SQL 数据库以获取每个客户在特定日期范围内的订单数。

我有一个订单列表如下

CustomerName       ClientID        DateOrdered
Customer No.2         10            2011-11-25
Customer No.3         11            2011-10-15
Customer No.3         11            2011-11-25

并且我希望能够找出特定客户在 2011 年 11 月 1 日到 2011 年 11 月 30 日之间下了多少订单,这应该会导致:

CustomerName       ClientID        Number
Customer No.3         11             1
Customer No.2         10             1

到目前为止,我已经设法得到了这个

SELECT CustomerName, ClientID, COUNT(*) AS Number      
FROM Orders t     
GROUP BY CustomerName, ClientID      
HAVING COUNT(*) =      
(SELECT MAX(Number)         
FROM          
(SELECT CustomerName, ClientID, COUNT(*) AS Number             
FROM Orders            
GROUP BY CustomerName, ClientID ) x       
WHERE CustomerName = t.CustomerName )

这给了我客户曾经下的每一个订单

CustomerName       ClientID        Number
Customer No.3         11             2
Customer No.2         10             1

我是在用正确的方法解决这个问题,还是有一种我完全忽略的更简单的方法!

【问题讨论】:

  • 题外话:为什么订单表中有 CustomerID 和 CustomerName?要获得任何其他客户信息,您必须加入客户表。如果您输入错误的客户名称并进行了更正,您将需要修改订单表以进行更改。所以只有外键客户 ID 会更准确......
  • 它实际上不应该在那里!谢谢你提醒我把它拿出来:)

标签: sql date range


【解决方案1】:

应该可以正常工作:

select CustomerName, ClientID, count(*) as Number
from Orders
where DateOrdered between '20111101' and '20111130'
group by CustomerName, ClientID

【讨论】:

  • @MichaelPowaga,为什么要使用子查询?
  • @MarkBannister,这不是必需的,但它不会改变执行计划(最后在我的情况下)。
  • @MichaelPowaga,为什么要使用它?
  • @MarkBannister,你是对的,在这种情况下,子查询没用。我已将其删除。
【解决方案2】:
select CustomerName, ClientID, count(*)
from
(
    select CustomerName, ClientID
    from Orders
    where datediff(mm, DateOrdered, getdate()) <= 1
 )a
group by CustomerName, ClientID

这样做是利用一个子查询,按给定月份的日期过滤行(这似乎是您要查找的内容)。然后它按CustomerName 和ClientID 分组并得到它们的订单总和。

【讨论】:

  • @kiwijus 很高兴为您提供帮助!请通过单击此帖子的复选标记将此答案标记为“已接受”。 :)
  • sum of ...?它真的适用于 SQL Server 吗? datediff(mm, DateOrdered, getdate()) - 如果可用,它会使用索引吗?
  • 只是出于好奇,在这种情况下,为什么 datediff 比 between 更好?
【解决方案3】:
select ClientID, max(CustomerName), count(*) 
from Orders 
where DateOrdered between '2011-11-01' and '2011-11-30'
group by ClientID

根据数据库,DateOrdered 选择的语法可能需要改变。

【讨论】:

  • 如果您的变量类似于 (Y-m-d),请不要忘记添加 'start_date 00:00:00' AND 'end_date 23:59:59'
  • 这个问题只暗示了日期 - 没有时间 - 否则我会提出...... DateOrdered &gt;= '2011-11-01' and DateOrdered &lt; '2011-12-01'。订单可能在 23:59:59.1 发生,between 语法会错过。
  • 对于日期范围,使用DateOrdered &gt;= '2011-11-01' AND DateOrdered &lt; '2011-12-01' 通常会为您提供更好的服务。通过使结束日期排他性(使用&lt;),您无需关心日期字段是否包含时间。
  • 好吧,我从来没有真正理解过这个问题,...但不止一次我发现自己因此而陷入困境。我从不调查它,但总是工作......:D
【解决方案4】:
SELECT
  c.CustomerName,
  count(o.OrderID) as Orders
FROM
  orders o
JOIN clients c ON o.ClientID = c.ClientID
WHERE
  o.DateOrdered BETWEEN '2011-11-01' AND '2011-11-20'
GROUP BY c.ClientID ;

【讨论】:

    猜你喜欢
    • 2012-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多