【发布时间】:2016-08-10 16:29:45
【问题描述】:
好的,所以我已经坚持了 2 天!我已经从语义的角度解决了它,但查询可能需要长达 10 分钟才能执行。我为此选择的数据库是 SQLite(出于我不想在此详细说明的原因),但我尝试在 SQL Server 2012 上运行相同的东西,它并没有对性能产生太大影响。
所以,问题是我有 2 张桌子
-
prices(product_id INT,for_date DATE,值 INT) -
events(starts_on DATE,ends_on DATE NULLABLE)
价格表中有大约 500K 行,事件表中有大约 100 行。
现在我需要编写一个查询来执行以下操作。
伪代码是:
- 对于每个事件:
- 如果事件有一个ends_on 值,那么获取所有具有匹配for_date 的product_id,对于不匹配的产品然后获取小于ends_on 值但大于该事件的starts_on 的最后一个for_date。
- ELSE 如果事件的 ends_on 日期为 NULL,则获取所有具有与 starts_on 匹配的 for_date 的 product_id,对于不匹配的产品,获取小于 starts_on 值的最后一个 for_date。李>
我在 SQL Server 2012 中编写的查询是
SELECT
sp.for_date, sp.value
FROM
prices sp
INNER JOIN
events ev ON (((ev.ends_on IS NOT NULL AND
(sp.for_date = (SELECT for_date
FROM prices
WHERE for_date <= ev.ends_on
AND for_date > ev.starts_on
ORDER BY for_date DESC
OFFSET 0 ROWS
FETCH NEXT 1 ROWS ONLY))))
OR
((ev.ends_on is null
and
(sp.for_date = (SELECT for_date
FROM prices
WHERE
for_date <= ev.starts_on_j
AND for_date > dateadd(day, -14, ev.starts_on)
order by for_date desc
offset 0 rows
fetch next 1 row only))))
);
顺便说一句,我还尝试使用部分数据创建临时表并对它们进行了相同的操作。它只是卡住了。
奇怪的是,如果我分别运行 2 个“OR”条件,响应时间是完美的!
更新
样本数据集和预期结果
价格条目
Product ID, ForDt, Value
1, 25-01-2010, 123
1, 26-01-2010, 112
1, 29-01-2010, 334
1, 02-02-2010, 512
1, 03-02-2010, 765
1, 04-02-2010, 632
1, 05-02-2010, 311
1, 06-02-2010, 555
2, 03-02-2010, 854
2, 04-02-2010, 625
2, 05-02-2010, 919
3, 20-01-2010, 777
3, 06-02-2010, 877
3, 10-03-2010, 444
3, 11-03-2010, 888
事件条目(为了更容易理解,我还添加了事件 ID)
Event ID, StartsOn, EndsOn
22, 27-01-2010, NULL
33, 02-02-2010, 06-02-2010
44, 01-03-2010, 13-03-2010
预期结果集
Event ID, Product ID, ForDt, Value
22, 1, 26-01-2010, 112
33, 1, 06-02-2010, 311
44, 1, 06-02-2010, 311
33, 2, 05-02-2010, 919
44, 2, 05-02-2010, 919
22, 3, 20-01-2010, 777
33, 3, 06-02-2010, 877
44, 3, 11-03-2010, 888
【问题讨论】:
-
如果可以显示查询和输出,将有助于了解查询在做什么
-
还显示了索引以及上面两个表与一些样本数据的关系
-
和EXPLAIN QUERY PLAN的输出。
-
你想要的答案应该是SQLite还是SQL Server?
-
我必须承认我很难理解这项任务。您正在从表价格中选择记录,但仅显示日期和价格。当您将记录与许多事件结合起来时,您最终会得到一个包含许多天数和许多价格的列表,其中许多可能是重复的,并且没有它们所指的产品和事件的信息。这似乎没有意义。