【问题标题】:MySQL select rows where given date lies between the dates stored in tableMySQL选择给定日期位于存储在表中的日期之间的行
【发布时间】:2015-11-21 15:04:18
【问题描述】:

假设我有一些数据,例如:

id  status activity_date
--- ------ -------------
101   R     2014-01-12
101   Mt    2014-04-27 
101   R     2014-05-18
102   R     2014-02-19

请注意,对于 id = 101 的行,我们在 2014-01-12 到 2014-04-26 和 2014-05-18 到当前日期之间有活动。

现在我需要选择 status = 'R' 并且日期是给定日期的最新日期的数据,例如如果我搜索 2014-02-02,我会找到在 2014-01-12 创建的状态行,因为该状态在当时对于实体 ID 101 仍然有效。

【问题讨论】:

  • 您是否特别要选择活动日期2014-02-02 而没有其他值?
  • @Scott,我想选择在选定日期的状态为 R(running) 的数据,例如“2014-02-02”
  • 这是数据仓库中的常见问题,被称为 Kimball 渐变维度。

标签: mysql sql date datetime


【解决方案1】:

试试这个:

select * from yourtable 
where status='R' and activity_date= '2014-02-02'

【讨论】:

  • 阅读问题下方的 OP 评论。
  • @SalmanA:- I want to select data which status R(running) on the selected date like '2014-02-02' 如果我接受这个,那么我发布的查询似乎是正确的。但我认为 OP 仍然没有明确说明他/她在寻找什么,特别是有问题的行 **which** activity_date 2014-02-02
  • description in bold 清楚地表明 OP 正在谈论日期范围。
【解决方案2】:

你可以试试

select id, status, activity_date 
from TABLE 
where status = "R" and activity_date = "2014-02-02"

其中 TABLE 是您的表的名称

【讨论】:

  • 也可以只使用SELECT * 而不是单独命名他的所有属性
  • 是的,但是如果有人要求简单的事情,我会尽量简单地展示它......也许他会读它......
  • 我不能选择它 activity_date = "2014-02-02" ,因为它是日期范围。前任。从(2014 年 1 月 12 日到 2014 年 4 月 26 日)和(2014 年 5 月 18 日到今天),101 个产品是 R(运行)。那么如何才能选择这个产品在“2014-02-02”上运行
  • 我不明白你为什么要针对我
  • 我也不明白你的意思。您只想选择 id = 101 吗?
【解决方案3】:

我认为你需要关注 ans

SELECT id,MAX(CAST(ACTIVITY_DATE AS date),MIN(CAST (ACTIVITY_DATE AS date)  
FROM Table_Name WHERE CAST('2014-02-02' AS date)
BETWEEN  MIN(CAST (ACTIVITY_DATE AS date) AND MAX(CAST(ACTIVITY_DATE AS date) 
 AND Status='R'
GROUP BY id

【讨论】:

    【解决方案4】:

    试试下面的

    SELECT *
    FROM your_relation
    WHERE status='R'
    AND activity_data="2014-02-02"
    

    【讨论】:

      【解决方案5】:

      如果我理解正确:

      第 1 步:将开始日期和结束日期行转换为列。为此,您必须根据此条件将表与自身连接:

      SELECT
          dates_fr.id,
          dates_fr.activity_date AS date_fr,
          MIN(dates_to.activity_date) AS date_to
      FROM test AS dates_fr
      LEFT JOIN test AS dates_to ON 
          dates_to.id = dates_fr.id AND
          dates_to.status = 'Mt' AND
          dates_to.activity_date > dates_fr.activity_date
      WHERE dates_fr.status = 'R'
      GROUP BY dates_fr.id, dates_fr.activity_date
      
      +------+------------+------------+
      | id   | date_fr    | date_to    |
      +------+------------+------------+
      |  101 | 2014-01-12 | 2014-04-27 |
      |  101 | 2014-05-18 | NULL       |
      |  102 | 2014-02-19 | NULL       |
      +------+------------+------------+
      

      第 2 步:剩下的很简单。将查询包装在另一个查询中并使用适当的 where 子句:

      SELECT * FROM (
          SELECT
              dates_fr.id,
              dates_fr.activity_date AS date_fr,
              MIN(dates_to.activity_date) AS date_to
          FROM test AS dates_fr
          LEFT JOIN test AS dates_to ON 
              dates_to.id = dates_fr.id AND
              dates_to.status = 'Mt' AND
              dates_to.activity_date > dates_fr.activity_date
          WHERE dates_fr.status = 'R'
          GROUP BY dates_fr.id, dates_fr.activity_date
      ) AS temp WHERE '2014-02-02' >= temp.date_fr and ('2014-02-02' < temp.date_to OR temp.date_to IS NULL)
      
      +------+------------+------------+
      | id   | date_fr    | date_to    |
      +------+------------+------------+
      |  101 | 2014-01-12 | 2014-04-27 |
      +------+------------+------------+
      

      SQL Fiddle

      【讨论】:

        【解决方案6】:

        我完全同意 Salman 的回答,该表的设计方式可以提高查询的准确性和可扩展性。但是,关于基于状态和日期范围的查询选择信息的问题可以表示为。

        SELECT * FROM Table_1
        WHERE ((status = 'R')
        AND ((activity_date BETWEEN '2014-01-12' AND '2014-04-26')
        OR activity_date  > CONVERT(DATETIME, '2014-05-17')))
        

        这将选择状态为“R”的所有数据,并将使用 BETWEEN 运算符获取所需范围;另外,final 运算符的转换是因为表达式作为数学表达式求值,需要显式转换。

        【讨论】:

          【解决方案7】:

          您可以进行查询以有效地为您提供截至日期的最多状态,例如

          SELECT
              id, 
              substr(max(concat(activity_date, status)),11) as status,
              max(activity_date) as activity_date
          FROM table
          WHERE activity_date <= '2014-02-02'
          GROUP by id;
          

          然后,类似于 Salman 的回答,您可以在另一个查询中使用此结果并查找所有状态为“R”的结果

          SELECT * from (
              SELECT
                  id,
                  substr(max(concat(activity_date, status)),11) as status,
                  max(activity_date) as activity_date
              FROM table
              WHERE activity_date <= '2014-02-02'
              GROUP by id
          ) AS temp WHERE temp.status = 'R';
          

          编辑:您可以使用子查询来识别相关的最大记录,而不是使用有问题的状态排序方法,因此原始查询将变为

          SELECT join1.* FROM table AS join1
          INNER JOIN (
              SELECT id, max(activity_date) as max_activity_date
              FROM table
              WHERE activity_date < '2014-02-02'
              GROUP BY id
          ) AS join2
          ON join1.id = join2.id AND join1.activity_date = join2.max_activity_date;
          

          以及完整的查询

          SELECT * from (
              SELECT join1.* FROM table AS join1
              INNER JOIN (
                  SELECT id, max(activity_date) as max_activity_date
                  FROM table
                  WHERE activity_date < '2014-02-02'
                  GROUP BY id
              ) AS join2
              ON join1.id = join2.id AND join1.activity_date = join2.max_activity_date
          ) AS temp WHERE temp.status = 'R';
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-02-24
            • 2012-06-18
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多