如何根据不同的时间范围从多个表中选择数据?

时间:2014-08-08 20:34:15

标签: php jquery mysql sql charts

我在MySQL中有两个表:

  • 访问

visits表如下所示:

+-------+-------------------+-----------+
|   id  |   date            |  user_id  |
+-------+-------------------+-----------+
|   1   |2014-08-01 05:23:00|       43  |
|   2   |2014-08-01 14:41:00|       21  |
|   3   |2014-08-02 23:54:00|       43  |
|   4   |2014-08-03 03:21:00|       43  |
|   5   |2014-08-03 04:19:00|       34  |
|   6   |2014-08-03 11:33:00|       43  |
|   7   |2014-08-04 12:21:00|       43  |
|   8   |2014-08-05 01:55:00|       43  |
|   9   |2014-08-06 06:13:00|       43  |
|  10   |2014-08-07 19:47:00|       43  |
+-------+-------------------+-----------+

points表如下所示:

+-------+-------------------+-----------+-------+----------+
|   id  |   date            |  user_id  | points|   status |
+-------+-------------------+-----------+-------+----------+
|   1   |2014-08-01 04:33:00|       43  |   10  |        0 |
|   2   |2014-08-02 05:21:00|       21  |   23  |        0 |
|   3   |2014-08-02 09:01:00|       43  |   32  |        1 |
|   4   |2014-08-02 01:21:00|       43  |   21  |        0 |
|   5   |2014-08-03 23:23:00|       34  |   54  |        0 |
|   6   |2014-08-04 20:34:00|       43  |   11  |        0 |
|   7   |2014-08-04 17:54:00|       43  |    9  |        0 |
|   8   |2014-08-04 03:45:00|       43  |   34  |        0 |
|   9   |2014-08-06 08:23:00|       43  |   76  |        0 |
|  10   |2014-08-07 11:43:00|       43  |   52  |        0 |
+-------+-------------------+-----------+-------+----------+

我想只执行1个查询并实现以下功能。

我想count visits表中user_id = 43date介于2014-08-012014-08-03之间的行count

我还想sum points points表格user_id = 43 date 2014-08-012014-08-03之间的行2014-08-04 2014-08-07 {1}}和Morris.js,状态为0。

之后,在同一个查询中,我想选择与上面相同的内容,但是在不同的时间范围内,例如:+---------------------+-----------+-------+-------+-------------+ | date | user_id | points| visits| points_count| +---------------------+-----------+-------+-------+-------------+ |2014-08-01-2014-08-03| 43 | 31 | 4 | 2 | |2014-08-04-2014-08-07| 43 | 182 | 4 | 5 | +---------------------+-----------+-------+-------+-------------+ 和{{1}}。

那里有什么问题可以解决这个问题吗?

(我实际上是这样做的,因为我想获取一个名为{{1}}的jQuery图表的数据。如果访问者选择了一个时间范围,我想得到12个数据集。根据访客选择的日期划分它。例如:如果他选择:2014-08-01至2014-08-01,我想向他显示当天的12个数据集。但是如果他选择例如:2014- 08-01至2014-08-06,然后我想向他显示6天的数据除以12。)

如果你在这里不明白,请告诉我,我会更好地解释。关键是我想要对数据集进行管理,并根据访问者的时间范围绘制图表。对于我的问题,MySQL逻辑是否是一个很好的解决方案?

编辑:

根据要求,我在这里显示了所需的结果:

{{1}}

我希望我已经正确计算了所有内容。

4 个答案:

答案 0 :(得分:3)

好的,所以这需要一点点工作,因为你必须独立地加入两个表...原因是因为一个不能具有1的状态而另一个可以..所以记住这个查询将完全返回您想要的。

QUERY:

SELECT 
    t.join_date as 'Time Frame',
    t1.user_id,
    t.num_visits,
    t1.num_points,
    t1.total_points
FROM
(   SELECT 
        CASE 
            WHEN DATE(date) >= '2014-06-01' AND DATE(date) <= '2014-07-10' THEN 1 
            WHEN DATE(date) >= '2014-08-05' AND DATE(date) <= '2014-08-07' THEN 2 
            ELSE 3
        END AS grouping_col,
        CONCAT(MIN(DATE(date)), ' - ', MAX(DATE(date))) as join_date,
        COUNT(id) as num_visits 
    FROM visits 
    WHERE user_id = 43
    GROUP BY grouping_col 
)t
LEFT JOIN 
(   SELECT
        CASE 
            WHEN DATE(date) >= '2014-06-01' AND DATE(date) <= '2014-07-10' THEN 1 
            WHEN DATE(date) >= '2014-08-05' AND DATE(date) <= '2014-08-07' THEN 2 
            ELSE 3
        END AS grouping_col,
        CONCAT(MIN(DATE(date)), ' - ', MAX(DATE(date))) as join_date,
        user_id,
        COUNT(id) as num_points,
        SUM(points) as total_points
    FROM points
    WHERE user_id = 43
      AND status = 0
    GROUP BY grouping_col
)t1 ON t1.grouping_col = t.grouping_col
WHERE t.grouping_col IN(1, 2) OR t1.grouping_col IN(1, 2)

注意:

您可以通过向CASE语句添加更多行来为此添加任意数量的时间帧...

参见演示:

FIDDLE

答案 1 :(得分:1)

更好的选择可能是实际使用存储过程并设置开始日期参数和结束日期参数,以便您可以选择所需的任何日期

答案 2 :(得分:1)

想到的唯一方法是执行两个不同的查询并使用UNION ALL

SELECT *
FROM
  (SELECT 
    count(v.id) AS visit_count, 
    count(p.id) AS point_count, 
    sum(p.points) AS points
  FROM visits v1
  JOIN points p1
  ON v1.user_id = p1.user_id
  WHERE v1.user_id = 43
  AND DATE(v1.date) BETWEEN '2014-08-01' AND '2014-08-03'
  AND p1.status = 0
  UNION ALL
  SELECT 
    count(v.id) AS visit_count, 
    count(p.id) AS point_count, 
    sum(p.points) AS points
  FROM visits v2
  JOIN points p2
  ON v2.user_id = p2.user_id
  WHERE v2.user_id = 43
  AND DATE(v2.date) BETWEEN '2014-08-04' AND '2014-08-07'
  AND p2.status = 0
) temp

答案 3 :(得分:0)

你可以尝试:

select count(id)
from visits
join points on points.user_id = visits.user_id
where date between 2014-08-04 00:00:00 and 2014-08-07 00:00:00
and visits.user_id = 43