|
您如何在一个日期稀疏的表与另一个日期详尽的表之间进行联接,以使稀疏日期之间的间隔取前一个稀疏日期的值?9 I6 j7 }4 r! T+ c
说明性示例:7 h: A! d' D3 U% z0 L( |$ m
PRICE table (sparse dates):
9 @; I5 ?0 e% I% m0 |0 ldate itemid price
+ |. W# { A: F# C* k% `2008-12-04 1 $1
! B8 k3 y7 }6 f: }; H& h2008-12-11 1 $35 }# r" ?& i5 s @' ?4 W
2008-12-15 1 $7( C' o0 u+ j$ l6 [$ l5 a
# i; `5 O+ r! N$ NVOLUME table (exhaustive dates):
4 Z1 [' N4 g& Y3 J, Ldate itemid volume_amt# `% w+ s; i- K
2008-12-04 1 12345
+ J2 x5 a/ b, @4 d! r/ E4 ]* x2008-12-05 1 234564 P1 i& f& B; Y$ z6 g1 }. ?1 Y
2008-12-08 1 34567+ Z4 s" o; ~% M5 Q
2008-12-09 1 ...- U: j6 o! s+ c+ Z6 f8 U+ A- o8 c9 }1 G
2008-12-10 1; d1 u2 o" Q! b! p m5 ~
2008-12-11 1
5 U- X3 u* N" S# W+ G& f3 Z2008-12-12 1' @6 f1 ?" h7 N/ r, p0 c
2008-12-15 1
: g7 d5 _0 Q3 n5 Z2008-12-16 1' F( M7 s. Z% a* n& e
2008-12-17 1
5 V: ^* m0 Z. @3 N: M# p! h2008-12-18 16 s: v. n2 b( z- V3 P4 z3 U
所需结果:$ Y" t+ ?, i: g) o
date price volume_amt
, j# |. X, s/ p) Y* E2008-12-04 $1 12345
5 ] o9 Y) q$ L$ b- B& _2008-12-05 $1 234561 y6 a/ h& Q) @1 W5 A: K
2008-12-08 $1 34567
B$ X- p& w# R1 F8 Q2008-12-09 $1 ...
7 e+ P5 I. \: Z/ J2008-12-10 $1; `9 b1 u8 R8 U& W& w, N4 Q6 G
2008-12-11 $3; J R, V9 s# }8 A
2008-12-12 $3
. R0 `) p7 r" p0 w( ~% d! Y2008-12-15 $7
- J+ {6 V' I$ M- l/ f* k2008-12-16 $7
8 u$ u3 V+ W# l% N5 K9 ]7 v2008-12-17 $7, f* h7 `" V3 K) r [3 w7 E
2008-12-18 $7# m' J1 {* T7 `3 h6 Y# ~5 e, D
更新:6 {5 F! f% D% D5 {
几个人提出了可以完成所需结果的相关子查询。(相关子查询=包含对外部查询的引用的子查询。)
' L# V- }8 e' G这将起作用;但是,我应该注意到,我使用的平台是MySQL,其相关子查询的优化效果很差。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。有没有使用相关子查询的任何方法?
9 K( J) M" _7 F, n, O0 G' f( x2 u
, |. ~. {- J9 U1 d0 h解决方案:. |" M" U! |, s) |5 k) ]! S/ x, r
7 M+ }. g/ _2 D
! b6 y2 d% u: }" C6 ~, I6 c
9 m8 G2 c u4 \, [2 j 这不像向稀疏表中的单个LEFT OUTER JOIN那样简单,因为您希望用最新的价格填充外部联接留下的NULL。; K$ z2 ^, u, A3 C6 u) }$ W
EXPLAIN SELECT v.`date`, v.volume_amt, p1.item_id, p1.price
3 l; D- s! ^7 e9 uFROM Volume v JOIN Price p10 r; M. M1 a& k
ON (v.`date` >= p1.`date` AND v.item_id = p1.item_id)) n) Q9 G; i, [: t! p
LEFT OUTER JOIN Price p28 G; A) p f b( o; c6 K( E! @
ON (v.`date` >= p2.`date` AND v.item_id = p2.item_id3 S1 p5 Y& i/ P* _
AND p1.`date` 该查询将“成交量”与“价格”中所有较早的行匹配,然后使用另一个联接来确保我们仅找到最新的价格。
0 F# @* N! }. z- ]& p" }我在MySQL 5.0.51上进行了测试。它既不使用相关子查询,也不使用分组依据。 b, [+ H: c8 W1 ?0 Q
编辑: 更新查询以匹配item_id以及日期。这似乎也可行。我在(date)和上创建了一个索引,(date,
( A$ A7 x* c% B* m" M& Kitem_id)并且EXPLAIN计划是相同的。(item_id, date)在这种情况下,索引为on可能更好。这是EXPLAIN的输出:/ K q! A' E; Z9 ^
+----+-------------+-------+------+---------------+---------+---------+-----------------+------+--------------------------------------+
/ g% E- _$ e0 g% k% _! \| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |. O$ ~, |0 d$ H3 @8 M$ ?
+----+-------------+-------+------+---------------+---------+---------+-----------------+------+--------------------------------------+5 `8 B. `1 J/ Z: ^) S
| 1 | SIMPLE | p1 | ALL | item_id | NULL | NULL | NULL | 6 | | , \( j# y/ q1 x, a& n- l1 C
| 1 | SIMPLE | v | ref | item_id | item_id | 22 | test.p1.item_id | 3 | Using where | : p/ U9 b* C- C
| 1 | SIMPLE | p2 | ref | item_id | item_id | 22 | test.v.item_id | 1 | Using where; Using index; Not exists | ' W# R! k2 X. u
+----+-------------+-------+------+---------------+---------+---------+-----------------+------+--------------------------------------+' b9 V; p, R/ E! z5 Z! c
但是我的数据集很小,优化可能取决于较大的数据集。您应该尝试使用更大的数据集来分析优化。
- [5 F3 o, T0 o. A( Z编辑: 我之前粘贴了错误的EXPLAIN输出。上面的一个已更正,并且显示了(item_id, date)索引的更好使用。 |
|