【问题标题】:MySQL query logic for fetching posts by dates用于按日期获取帖子的 MySQL 查询逻辑
【发布时间】:2011-12-26 19:20:14
【问题描述】:

任何人都可以为执行以下操作的 MySQL 查询中的逻辑提供建议:

  • 至少选择 100 个帖子
  • 选择加载想法的最后一个月的所有帖子,例如,如果 100 个帖子加载了 9 月中途的帖子,则应加载整个 9 月的帖子,而不是中途切断。李>

不幸的是,我知道第二个选项在 MySQL 中是不可能的,所以我正在寻求一些帮助。

干杯。

【问题讨论】:

  • 至少选择 100 个是什么意思?如果帖子少于 100 个怎么办?你的意思是最多吗?
  • 不,我认为他的意思是至少 100。返回 100+ 个结果。如果第 100 个结果不是其所属月份的最旧结果,则最多包括该月最旧的结果。 Dan,您反对使用存储过程来实现这一点吗?
  • 让我试着澄清一下:我希望这个查询逐月加载帖子,直到加载的帖子数量等于或大于 100。
  • @D.N.确切地;在这一点上,我不排除任何可能性。

标签: php mysql logic


【解决方案1】:

只计算子查询中第 100 行的月份并使用 BETWEEN 条件中的值

你基本上需要什么:

  • 查找第 100 行的日期 (date_a)
  • 查找 date_a (date_b) 月份的第一天
  • 查找比 date_b 新的所有行

因此,

SELECT created as date_a
FROM posts
ORDER BY created DESC
LIMIT 99, 1

SELECT
  (LAST_DAY(created) + INTERVAL 1 DAY - INTERVAL 1 MONTH) as date_b
FROM posts
ORDER BY created DESC
LIMIT 99, 1

后者用作子查询的最后一个查询是你的作业 =)

【讨论】:

  • 我不知道我自己怎么没有想到这个!谢谢你的想法。
【解决方案2】:

在意识到您正在寻找特定于 mySQL 的解决方案之前,我开发了一个适用于 SQL Server 的答案。但是,我无权访问 mySQL 实例来验证语法 - 我确信它仍然坏了,但真的很接近它应该是的。我很确定 searchDate 连接失败,因此假设语法已更正,将返回意外结果。

此解决方案假定您的源表名为thoughts,重要的列是ThoughtIDThoughtTime。显然,您需要根据需要对其进行自定义:

SQL 服务器:

DECLARE @Results TABLE (
   ThoughtID   int,
   ThoughtTime datetime)
DECLARE @date       date
DECLARE @minResults int
DECLARE @totResults int

SET @minResults = 100
SET @totResults = (SELECT COUNT(1) FROM thougts)
SET @date       = CONVERT(CHAR(4), YEAR(GETDATE()), 100) + '-' + CONVERT(CHAR(2), MONTH(GETDATE()),120) + '-01'

IF @totResults <= @minResults
BEGIN
   -- Not enough results, grab everything
   SELECT   ThoughtID, ThoughtTime
   FROM     thougts
   ORDER BY ThoughtTime DESC
END ELSE
BEGIN
   WHILE (SELECT COUNT(1) FROM @Results) < @minResults
   BEGIN
      DELETE FROM @Results -- Can be optimized
      SET @date    = DATEADD(m, -1, @date)
      INSERT INTO @Results (ThoughtID, ThoughtTime) (
         SELECT ThoughtID, ThoughtTime
         FROM   thougts
         WHERE  ThoughtTime >= @date)
   END
   SELECT   *
   FROM     @Results
   ORDER BY ThoughtTime DESC
END

mySQL(未经测试,需要改进):

CREATE PROCEDURE TEST()
BEGIN
CREATE TEMPORARY TABLE Results (
   ThoughtID   int,
   ThoughtTime datetime);
DECLARE searchDate date;
DECLARE minResults int;
DECLARE totResults int;

SET minResults = 100;
SET totResults = (SELECT COUNT(1) FROM thougts);
SET searchDate = CONVERT(YEAR(CURRENT_TIMESTAMP()), CHAR(4)) + '-' + CONVERT(MONTH(CURRENT_TIMESTAMP()), CHAR(2)) + '-01';

IF totResults <= minResults
THEN
   SELECT   ThoughtID, ThoughtTime
   FROM     thougts
   ORDER BY ThoughtTime DESC;
ELSE
   WHILE (SELECT COUNT(1) FROM Results) < minResults DO
      DELETE FROM Results; -- Can probably be optimized
      SET searchDate = DATE_SUB(searchDate, INTERVAL 1 MONTH);
      INSERT INTO Results (ThoughtID, ThoughtTime) (
         SELECT ThoughtID, ThoughtTime
         FROM   thougts
         WHERE  ThoughtTime >= searchDate);
   END WHILE;
   SELECT *
   FROM Results
   ORDER BY ThoughtTime DESC;
END IF;
)
END

如果我在接下来的几天内可以访问一个 mySQL 实例,我会尝试更多地清理它。否则,希望其他 SO 用户可以看看。

【讨论】:

  • 废话,我刚刚意识到您要求在 mySQL 而不是 SQL Server 中提供解决方案。我会看看我是否可以适当地调整语法。
  • 我知道你对存储过程做了什么,但@newtover 提到的另一种方法更优雅一点,需要更少的开销。
猜你喜欢
  • 2020-11-18
  • 1970-01-01
  • 1970-01-01
  • 2019-06-03
  • 1970-01-01
  • 1970-01-01
  • 2018-05-24
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多