我有一个我想简化的查询:
select
sequence,
1 added
from scoredtable
where score_timestamp=1292239056000
and sequence
not in (select sequence from scoredtable where score_timestamp=1292238452000)
union
select
sequence,
0 added
from scoredtable
where score_timestamp=1292238452000
and sequence
not in (select sequence from scoredtable where score_timestamp=1292239056000);
有什么想法吗?基本上我想从同一个表中提取两个时间戳值之间不同的所有序列。使用colum“added”表示行是否为新行或是否已删除行。
来源表:
score_timestamp sequence
1292239056000 0
1292239056000 1
1292239056000 2
1292238452000 1
1292238452000 2
1292238452000 3
之间的示例(1292239056000,1292238452000) 查询结果(2行):
sequence added
3 1
0 0
之间的示例(1292238452000,1292239056000) 查询结果(2行):
sequence added
0 1
3 0
之间的示例(1292239056000,1292239056000) 查询结果(0行):
sequence added
答案 0 :(得分:2)
此查询获取在两个时间戳中仅出现一次的所有sequences
,并检查它是否出现在第一个时间戳或第二个时间戳中。
SELECT
sequence,
CASE WHEN MIN(score_timestamp) = 1292239056000 THEN 0 ELSE 1 END AS added
FROM scoredtable
WHERE score_timestamp IN ( 1292239056000, 1292238452000 )
AND ( 1292239056000 <> 1292238452000 ) -- No rows, when timestamp is the same
GROUP BY sequence
HAVING COUNT(*) = 1
它会返回您想要的结果:
sequence added
3 1
0 0
答案 1 :(得分:0)
给出两个时间戳
SET @ts1 := 1292239056000
SET @ts2 := 1292238452000
您可以通过以下方式获取和删除
SELECT s1.sequence AS sequence, 0 as added
FROM scoredtable s1 LEFT JOIN
scoredtable s2 ON
s2.score_timestamp = @ts2 AND
s1.sequence = s2.sequence
WHERE
s1.score_timestamp = @ts1 AND
s2.score_timestampe IS NULL
UNION ALL
SELECT s2.sequence, 1
FROM scoredtable s1 RIGHT JOIN
scoredtable s2 ON s1.score_timestamp = @ts1 AND
s1.sequence = s2.sequence
WHERE
s2.score_timestamp = @ts2 AND
s1.score_timestampe IS NULL
取决于行数和统计数据,上面的查询可能会执行得更好然后分组并且有count(*)= 1版本(我认为总是需要全表扫描,而上面的联合应该能够做到2 x anti-join,可能会更好)
如果您有大量数据集,请告诉我们哪个更快(使用SQL_NO_CACHE进行测试以获得可比较的结果)