【问题标题】:MySQL Selecting Info based on timestamp of another tableMySQL基于另一个表的时间戳选择信息
【发布时间】:2017-02-25 17:47:12
【问题描述】:

编辑:我已将其放在 PHP 和 MySQL 类别中,因为我相信可能有一种方法可以使用多个查询来做到这一点,并使用 PHP 将它们联系在一起。我宁愿不这样做……但归根结底,解决方案就是解决方案……

希望这对某人来说很容易思考,但我肯定被困在这里!在我的网站上,我允许用户发布提要/消息,并且他们可以根据需要随时切换会员资格。我想根据他们发布每个提要时的成员身份来运行一些统计数据,而不仅仅是他们当前的成员身份。例如,我想查看每个会员发布了多少订阅源。现在,我可以运行计数并加入用户、提要和会员表,但这会根据每个用户当前的会员资格计算每个用户的每个提要,这不一定是他们发布时的会员资格。我希望这是有道理的。

由于我们的数据库中已经有许多提要,我无法在提要表中添加一列来显示发布用户的会员类型。这是我的表格(缩写)的样子,看看是否有人对如何执行此操作有疑问:

用户表

id  username  membershipid
1   John Doe  1

成员表

id  membershipname
1   Membership #1
2   Membership #2
3   Membership #3

会员历史记录表

id  membershipsid  usersid  unix_timestamp
1   1              1        1476635544.33
2   2              1        1476641890.11
3   3              1        1476642124.2
4   1              1        1476642161.51

Feed 表

id  unix_timestamp     usersid
1   1476641716.809361  1
2   1476641783.866863  1
3   1476641822.779324  1
4   1476641904.066237  1
5   1476641973.767174  1
6   1476642182.821472  1

使用 unix_timestamps 很难快速查看...但我想要一个解决方案来提供这个:

按成员资格表的订阅源计数

membershipid  feedcount
1             4
2             2
3             0

到目前为止,我已经尝试了很多东西,但它们最终都提供了用户当前的会员资格......例如:

SELECT
    a.MembershipName MembershipName,
    COUNT(*) Feeds
FROM (SELECT
        m.membership_name MembershipName
    FROM feeds f
    JOIN users u ON f.usersid = u.id
        JOIN memberships m ON u.membership_id = m.id
    GROUP BY f.id
    ORDER BY f.unix_timestamp DESC) a
    GROUP BY a.MembershipName
ORDER BY a.MembershipName

但这对会员历史表没有任何作用,所以我的输出表是:

按成员资格表的订阅源计数

membershipid  feedcount
1             6
2             0
3             0

这是错误的,因为它应该是 1->4, 2->2 & 3->0,如上表所示。任何人的任何想法?

【问题讨论】:

  • 与您的情况类似:stackoverflow.com/questions/4070476/… 他们的classification 表将是您的会员历史表,他们的closed_cases 表将是您的提要表
  • 这是一个非常相似的问题......我将看看我是否可以复制它。我遇到的一个问题是,他的解决方案只能通过添加一个带有“结束时间”的新列来解决。我希望我的结束时间成为 members_history 表中该用户的下一个值

标签: php mysql datetime


【解决方案1】:

注意 #1 - 您要执行的查询非常昂贵,我的建议是在发布提要时将当前的成员身份简单地保存到提要表中

注意 #2 - 下面的查询假定会员历史记录始终包含每个用户至少一个条目,不仅在更改时(因此第一次分配历史记录时创建历史记录)

我认为您的解决方案的方式是“我如何在时间 X 查询会员 id 值?”,答案很简单,它是时间 X 之前最近更改的值:

SELECT h.membershipsid
FROM membershipshistory h
WHERE h.usersid = {USERID} AND h.unix_timestamp < {X}
ORDER BY h.unix_timestamp DESC
LIMIT 1

接下来是“如何列出所有提要以及会员 ID,其中 X 是提要发布的时间?

SELECT
  feeds.id,
  feeds.usersid,
  (
    SELECT h.membershipsid
    FROM membershipshistory h
    WHERE h.usersid = feeds.usersid AND h.unix_timestamp < feeds.unix_timestamp
    ORDER BY h.unix_timestamp DESC
    LIMIT 1
  ) AS historical_membershipsid
FROM
  feeds

哪些输出(来自我的样本数据):

+------+---------+--------------------------+
| id   | usersid | historical_membershipsid |
+------+---------+--------------------------+
|    1 |       1 |                        1 |
|    2 |       1 |                        2 |
|    3 |       1 |                        3 |
+------+---------+--------------------------+

从这个你的解决方案应该是微不足道的,只需将整个查询放在一个视图或子查询中,并按 history_membershipsid 分组,但请记住它非常昂贵。

更新

如果最终解决方案不是那么明显,我深表歉意,这是使用历史数据计算每个成员的订阅源的最终查询:

SELECT
  hf.historical_membershipsid AS membershipsid,
  COUNT(hf.id) AS feedcount
FROM (
  SELECT
    feeds.id,
    feeds.usersid,
    (
      SELECT h.membershipsid
      FROM membershipshistory h
      WHERE h.usersid = feeds.usersid AND h.unix_timestamp < feeds.unix_timestamp
      ORDER BY h.unix_timestamp DESC
      LIMIT 1
    ) AS historical_membershipsid
  FROM
    feeds) AS hf
GROUP BY
  hf.id

【讨论】:

  • 好的...我已经看了一些你的建议并玩了一点。我可以看到你要去哪里,但我同意你的观点,这是非常昂贵的。我相信必须有一个更简单的方法。您的建议的一个问题是您如何获得...'WHERE h.usersid = {USERID} AND h.unix_timestamp
  • 在第二个 sn-p 中,我使用第一个查询作为字段子选择,这意味着子查询针对 feeds 表的每一行进行评估,每次替换“feeds.usersid” " 与当前用户 id...
  • 啊..当然。我看的不够大。我现在可以看到了。抱歉……我又看了一遍
  • 对不起,我用最终查询更新了我的答案,看看那个结果是否给你你期望的输出。
  • 好的很好...我可以从你的回答中得到我需要的东西。我不确定它是否真的是现实世界应用程序的“最佳”解决方案,因为我所要求的对于我的设置可能不是一个好主意......但基于我的设置,你的回答很好!谢谢
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-05-09
  • 1970-01-01
  • 2015-03-14
  • 2019-02-14
  • 2021-01-26
  • 1970-01-01
  • 2021-02-05
相关资源
最近更新 更多