MySQL查询拼图 - 寻找什么将是最近的日期
题
我看一切都结束了还没有找到一种智能的方式来处理这个问题,但我觉得肯定是一个可能的:
历史数据的一个表具有季度信息:
CREATE TABLE Quarterly (
unique_ID INT UNSIGNED NOT NULL,
date_posted DATE NOT NULL,
datasource TINYINT UNSIGNED NOT NULL,
data FLOAT NOT NULL,
PRIMARY KEY (unique_ID));
历史数据的另一表(这是非常大的)包含每日信息:
CREATE TABLE Daily (
unique_ID INT UNSIGNED NOT NULL,
date_posted DATE NOT NULL,
datasource TINYINT UNSIGNED NOT NULL,
data FLOAT NOT NULL,
qtr_ID INT UNSIGNED,
PRIMARY KEY (unique_ID));
在qtr_ID字段是不是每天的数据的饲料的一部分填充数据库 - 相反,我要追溯填充与Quarterly.unique_ID行ID每日表qtr_ID领域,使用什么将是最近的上季度的数据Daily.date_posted该数据源。
例如,如果季度数据是
101 2009-03-31 1 4.5结果 102 2009-06-30 1 4.4结果 103 2009-03-31 2 7.6结果 104 2009-06-30 2 7.7结果 105 2009-09-30 1 4.7
和每日数据是
1001 2009-07-14 1 3.5 ??结果 1002 2009-07-15 1 3.4 &&结果 1003 2009-07-14 2 2.3 ^^
那么我们希望的? qtr_ID字段被分配“102”作为最近一个季度在该日期数据源,和&&也将是“102”,和^^将是“104”。
的挑战包括两个表(特别是每日表)实际上非常大,它们不能被归一化以除掉重复日期的或以其他方式进行了优化,并且对于某些每日条目不存在前述季度条目。
我已经尝试了多种连接的,使用DATEDIFF(其中的挑战是找到DATEDIFF大于零的最小值),以及其他的尝试,但没有为我工作 - 通常我的语法是打破地方。任何想法表示欢迎 - 我会执行任何基本的想法或概念,并报告
。解决方案
刚子查询使用类似的季度ID:
(
SELECT unique_ID
FROM Quarterly
WHERE
datasource = ?
AND date_posted >= ?
ORDER BY
unique_ID ASC
LIMIT 1
)
当然,这可能不会给你最好的性能,并假定日期加到季度顺序(否则order by date_posted
)。但是,应该解决您的问题。
您可以使用此子查询您INSERT
或UPDATE
陈述你的qtr_ID
现场为您Daily
表中的值。
其他提示
下面似乎工作完全按照预期,但它肯定是丑(三调用同一DATEDIFF!),或许可以看到一个工作查询别人可能进一步降低,或改进:
UPDATE Daily SET qtr_ID = (select unique_ID from Quarterly
WHERE Quarterly.datasource = Daily.datasource AND
DATEDIFF(Daily.date_posted, Quarterly.date_posted) =
(SELECT MIN(DATEDIFF(Daily.date_posted, Quarterly.date_posted)) from Quarterly
WHERE Quarterly.datasource = Daily.datasource AND
DATEDIFF(Daily.date_posted, Quarterly.date_posted) > 0));
在此查询更多的工作,我结束了巨大的性能改进了原有的概念。最重要的改进是每日,每季度表都在创造指数 - 在日常生活中,我创建的索引上(数据源,date_posted)和(date_posted,数据源)使用BTREE和(数据源)使用HASH,并在季报和我一样的事情。这是矫枉过正,但它确信我有一个选项,查询引擎可以使用。该查询时间缩短到了什么它已经不到1%。 (!!)
然后,我才知道,给我的具体情况我可以使用MAX()而不是ORDER BY和LIMIT所以我使用MAX()的调用,以获得相应的UNIQUE_ID。由约20%降低的查询时间。
最后,我了解到,与InnoDB存储引擎,我可以细分日报表,我与任何一个查询,这让我更新块多线程一个小肘油脂和脚本的查询。并行处理行之有效,每个线程线性地减小查询时间。
所以,这是比我自己第一次尝试更好的字面进行1000次基本的查询是:
UPDATE Daily
SET qtr_ID =
(
SELECT MAX(unique_ID)
FROM Quarterly
WHERE Daily.datasource = Quarterly.datasource AND
Daily.date_posted > Quarterly.dateposted
)
WHERE unique_ID > ScriptVarLowerBound AND
unique_ID <= ScriptVarHigherBound
;