【问题标题】:counting occurrences between dates of different date intervals计算不同日期间隔的日期之间的发生次数
【发布时间】:2018-08-28 08:47:18
【问题描述】:

我有一个查询给我这样的表格:

 Person | Date_IN | Date_OUT | Structure

一年中一个人多次进入和退出,进入和退出也可能是同一天。

我想在一年中的某一天计算每个结构中有多少人。

最终目标是在给定期间(3 月 1 日 --> 3 月 31 日)获得每个结构每天的总人数。

【问题讨论】:

  • DATE_INDATE_OUT 列实际上是日期,并且不包含时间组件吗?如果我早上进楼,下午离开,我朋友下午离开后进楼,任何时候楼里最多只有一个人;你需要处理这些案件吗?这感觉就像你在尝试用 SQL 解决它之前需要对过程和要求更严格一些,或者至少更严格地表达问题空间。
  • 是的,DATE_IN e DATE_OUT 有点像 2018-03-07。我只需要计算那一天的存在。 (人们住 1 天或更多天......就像酒店一样)
  • 描述你如何计算每个结构中有多少人。如果某人在 3 月 1 日入住,并在 3 月 3 日退房,他是否在 3 月 2 日入住
  • @keebOo 。 . .请问另一个问题。提供样本数据、期望的结果、一天中有多少人“在”结构中是什么意思。涵盖诸如人们在结构中超过一天的情况,并说明数据中是否存在任何异常情况,例如一个人多次输入而没有输出。

标签: mysql sql date datetime


【解决方案1】:

我相信以下方法会起作用。它假定您有一个日期表(由一列组成,其中包含 1950 年到 2050 年之间的所有日期),并且您只需将其与人员签入/签出表连接起来:

SELECT dates.date, Structure, COUNT(DISTINCT Person) Persons_on_That_Date
FROM dates
LEFT JOIN turndata ON dates.date BETWEEN Date_IN AND Date_OUT
WHERE dates.date BETWEEN '2018-03-01' AND '2018-03-31'
GROUP BY dates.date, Structure
ORDER BY Structure, dates.date

Demo Here

注意:以上假设包含外出日期(该人在该日期被计为inside)。如果 out date 是独占的,则 ON 子句变为:

... ON Date_IN <= dates.date AND dates.date < Date_OUT

【讨论】:

  • 不,会的。我提到过使用日期表。
  • 如果我是你,我会等待 OP 构建一个示例。
  • 添加了小提琴。参见房间 2 示例。
  • @SalmanA 阅读并查看演示,似乎正确,下一步是我需要的最终解决方案是:我有 1 年“调查”,3 个结构,约 600 人 并且需要知道一年中的每一天 .... 某种方式来进行单个查询?或者我需要每天重复这个过程? (例如,可能在自定义 php 页面上有一个循环)
  • 我已经等了太久才能对问题进行编辑或得到适当的答复;除了添加以下评论外,不再花时间在这上面:CROSS JOIN 带有结构的日期表和 LEFT JOIN ... BETWEEN 带有 turndata 表。
【解决方案2】:

请使用以下查询,数据按特定时间范围的结构分组。

SELECT structure, COUNT(DISTINCT person) as no_of_person
FROM table_name
WHERE DATE(Date_IN) BETWEEN '2018-08-01' AND '2018-08-31'
GROUP BY structure

【讨论】:

  • 如果这个人在 07-28 进入并在 08-02 退出怎么办?
  • @KeebOo 已指定“我想计算一年中的特定日期,每个结构中有多少人。”
  • @JERRY 考虑添加一些文字来解释您的查询。
  • @Strawberry ... 如果 PERSON_1 进入第 1 天并退出该月的第 5 天,PERSON_2 进入第 3 天并退出第 7 天:第 1 天 = 1,第 2 天 = 1,第 3 天 = 2,第 4 天 = 2,第 5 天 = 1,第 6 天 = 1,第 7 天 = 0
【解决方案3】:

你说同一天和同一个人不能有多个date_in,因为一个人至少在一天。因此,对于给定的日期,我们只需要查看每个人在此之前的最新事件,以查看该人是否在/当时。

这些是步骤:

  • 动态创建所需天数的数据集
  • 加入表并获得每人直到那一天的最后一个date_in
  • 再次加入表以获取最后的记录
  • 每天汇总并统计出席人数

这是:

select
  data.day
  sum(t.date_in is not null and (t.date_out is null or t.date_out = data.day)) as count_in
from
(
  select days.day, t.person, max(t.date_in) as max_date_in
  from (select date '2018-03-01' as day union all ...) days
  left join t on t.date_in <= days.day
  group by days.day, t.person
) data
left join t on t.person = data.person and t.date_in = data.max_date_in
group by data.day
order by data.day;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-26
    • 1970-01-01
    • 1970-01-01
    • 2020-02-14
    • 2012-06-28
    相关资源
    最近更新 更多