我有SELECT * FROM table ORDER BY tick,refid
的以下(简化)结果:
tick refid value
----------------
1 1 11
1 2 22
1 3 33
2 1 1111
2 3 3333
3 3 333333
注意refid 1(tick 3)和refid 2(ticks 2和3)的“缺失”行
如果可能,如何使用value
的最新优先refid
进行查询以添加这些缺失的行? “最近”表示具有与缺失行相同的refid的行的值和最大的tick,使得tick小于缺失行的tick。 e.g。
tick refid value
----------------
1 1 11
1 2 22
1 3 33
2 1 1111
2 2 22
2 3 3333
3 1 1111
3 2 22
3 3 333333
附加条件:
我正在使用MySQL,现在无法更改数据库。随意用另一种方言发表答案,以帮助讨论,但我会选择MySQL方言中的答案而不是其他方言。
是的,我知道这可以在代码中完成,我已经实现了。我只是好奇是否可以使用SQL。
答案 0 :(得分:3)
当给定的tick-refid组合不存在时,应该返回value
什么?在这个解决方案中,我只返回给定refid的最低值。
<强>修订强>
我已经更新了逻辑,以确定在null的情况下使用什么值。应该注意的是,我假设ticks + refid在表中是唯一的。
Select Ticks.tick
, Refs.refid
, Case
When Table.value Is Null
Then (
Select T2.value
From Table As T2
Where T2.refid = Refs.refId
And T2.tick = (
Select Max(T1.tick)
From Table As T1
Where T1.tick < Ticks.tick
And T1.refid = T2.refid
)
)
Else Table.value
End As value
From (
Select Distinct refid
From Table
) As Refs
Cross Join (
Select Distinct tick
From Table
) As Ticks
Left Join Table
On Table.tick = Ticks.tick
And Table.refid = Refs.refid
答案 1 :(得分:0)
如果您事先知道'tick'和'refid'值是什么,
如果您不确切知道'tick'和'refid'值是什么,您可能仍然可以使用此方法,但不是静态帮助程序表,而是必须动态生成。
答案 2 :(得分:0)
为了让插入的对(list,refid)列表得到一个完整的列表:
SELECT a.tick, b.refid
FROM ( SELECT DISTINCT tick FROM t) a
CROSS JOIN ( SELECT DISTINCT refid FROM t) b
现在从该查询中减去现有的:
SELECT a.tick tick, b.refid refid
FROM ( SELECT DISTINCT tick FROM t) a
CROSS JOIN ( SELECT DISTINCT refid FROM t) b
MINUS
SELECT DISTINCT tick, refid FROM t
现在你可以用t加入以获得最终查询(注意我使用内部联接+左联接来获得以前的结果,但你可以适应):
INSERT INTO t(tick, refid, value)
SELECT c.tick, c.refid, t1.value
FROM ( SELECT a.tick tick, b.refid refid
FROM ( SELECT DISTINCT tick FROM t) a
CROSS JOIN ( SELECT DISTINCT refid FROM t) b
MINUS
SELECT DISTINCT tick, refid FROM t
) c
INNER JOIN t t1 ON t1.refid = c.refid and t1.tick < c.tick
LEFT JOIN t t2 ON t2.refid = c.refid AND t1.tick < t2.tick AND t2.tick < c.tick
WHERE t2.tick IS NULL
答案 3 :(得分:0)
以下有太多的子选择符合我的口味,但它会在MySQL中生成所需的结果,只要每个tick和每个refid在表中至少单独出现一次。
从一个生成每对tick和refid的查询开始。下面使用该表来生成对,因此如果任何tick不会出现在基础表中,它也将从生成的对中丢失。对于refids也是如此,尽管“所有refid将具有tick = 1的值”的限制应该确保后者永远不会发生。
SELECT tick, refid FROM
(SELECT refid FROM chadwick WHERE tick=1) AS r
JOIN
(SELECT DISTINCT tick FROM chadwick) AS t
使用此方法,通过等同于refid并且θ≥ -joining on tick,生成每个缺失的tick,refid对以及表中存在的最大tick。按生成的tick进行分组,refid,因为每个对只需要一行。过滤掉现有tick,refid对的关键是HAVING
子句。严格来说,你可以省略HAVING
;生成的查询将返回现有行及其现有值。
SELECT tr.tick, tr.refid, MAX(c.tick) AS ctick
FROM
(SELECT tick, refid FROM
(SELECT refid FROM chadwick WHERE tick=1) AS r
JOIN
(SELECT DISTINCT tick FROM chadwick) AS t
) AS tr
JOIN chadwick AS c ON tr.tick >= c.tick AND tr.refid=c.refid
GROUP BY tr.tick, tr.refid
HAVING tr.tick > MAX(c.tick)
从上面的一个最终选择作为子选择,加入到原始表中以获取给定ctick的值,返回表的新行。
INSERT INTO chadwick
SELECT missing.tick, missing.refid, c.value
FROM (SELECT tr.tick, tr.refid, MAX(c.tick) AS ctick
FROM
(SELECT tick, refid FROM
(SELECT refid FROM chadwick WHERE tick=1) AS r
JOIN
(SELECT DISTINCT tick FROM chadwick) AS t
) AS tr
JOIN chadwick AS c ON tr.tick >= c.tick AND tr.refid=c.refid
GROUP BY tr.tick, tr.refid
) AS missing
JOIN chadwick AS c ON missing.ctick = c.tick AND missing.refid=c.refid
;
示例表上的效果以及(tick, refid)
和(refid, tick)
索引:
+----+-------------+------------+-------+-------------------+----------+---------+----------+------+---------------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra | +----+-------------+------------+-------+-------------------+----------+---------+----------+------+---------------------------------+ | 1 | PRIMARY | <derived2> | ALL | NULL | NULL | NULL | NULL | 3 | | | 1 | PRIMARY | c | ALL | tick_ref,ref_tick | NULL | NULL | NULL | 6 | Using where; Using join buffer | | 2 | DERIVED | <derived3> | ALL | NULL | NULL | NULL | NULL | 9 | Using temporary; Using filesort | | 2 | DERIVED | c | ref | tick_ref,ref_tick | ref_tick | 5 | tr.refid | 1 | Using where; Using index | | 3 | DERIVED | <derived4> | ALL | NULL | NULL | NULL | NULL | 3 | | | 3 | DERIVED | <derived5> | ALL | NULL | NULL | NULL | NULL | 3 | Using join buffer | | 5 | DERIVED | chadwick | index | NULL | tick_ref | 10 | NULL | 6 | Using index | | 4 | DERIVED | chadwick | ref | tick_ref | tick_ref | 5 | | 2 | Using where; Using index | +----+-------------+------------+-------+-------------------+----------+---------+----------+------+---------------------------------+
正如我所说,选择太多了。临时表可能会有所帮助。
检查丢失的刻度:
SELECT clo.tick+1 AS missing_tick
FROM chadwick AS chi
RIGHT JOIN chadwick AS clo ON chi.tick = clo.tick+1
WHERE chi.tick IS NULL;
这将返回至少一行,其中tick等于1 +表中的最大刻度。因此,可以忽略此结果中的最大值。