查询
(SELECT timest, `char`, exp_cnt AS XP FROM `charac` WHERE DATE(timest)='2017-01-30')
UNION
(SELECT timest, `char`, -exp_cnt AS XP FROM `charac` WHERE DATE(timest)=ADDDATE('2017-01-30',-1))
ORDER BY `char` ASC
LIMIT 50
给我这个结果:
如果日期为01-29
,则值通常不应为0
我尝试通过复制粘贴并运行第二个SELECT
:
SELECT timest, `char`, -exp_cnt AS XP FROM `charac` WHERE DATE(timest)=ADDDATE('2017-01-30',-1)
ORDER BY `char` ASC
我得到了正确的结果!
为什么呢?我很迷惑。 UNION ALL
无效。
答案 0 :(得分:1)
首先,您应该使用union all
而不是union
,除非您想要承担删除重复项的开销。
其次,您在查询中有limit
。因此,您的结果可能正在生成,它们只是在列表的下方并截止。
如果您关心2017-01-29发生的事情,请按日期对列表进行排序并按比例进行比较:
(SELECT timest, `char`, exp_cnt AS XP
FROM `charac`
WHERE DATE(timest) = '2017-01-30'
) UNION ALL
(SELECT timest, `char`, -exp_cnt AS XP
FROM `charac`
WHERE DATE(timest) = ADDDATE('2017-01-30', -1)
)
ORDER BY timest ASC
LIMIT 50;
这可能不是您想要的最终结果,但您至少会看到所有行都被计算在内。
如果您在29日不想要0值,那么请将其明确地放入查询中:
(SELECT timest, `char`, exp_cnt AS XP
FROM `charac`
WHERE DATE(timest) = '2017-01-30'
) UNION ALL
(SELECT timest, `char`, -exp_cnt AS XP
FROM `charac`
WHERE DATE(timest) = ADDDATE('2017-01-30', -1) AND
exp_cnt <> 0
)
ORDER BY timest ASC
LIMIT 50;
答案 1 :(得分:1)
每天有多少行?我敢打赌,30日不到50。我敢打赌UNION
获得了30日的所有行,然后是29日的所有行。这可以解释它。
要进一步测试我的理论,请分别运行SELECT
中的每个UNION
。
另一项测试:交换SELECTs
中的两个UNION
。现在它可能会丢失30日的部分行。
如果您想要两者中的前50个,请使用以下模式:
( SELECT ... ORDER BY timest LIMIT 50 )
UNION ALL
( SELECT ... ORDER BY timest LIMIT 50 )
ORDER BY timest LIMIT 50
如果您还需要OFFSET
,它会变得更加混乱,但是可能:
比方说,第3页:
LIMIT 150
- 确保每个至少150(如果有的话)LIMIT 100, 50
- 在<{em> ORDER BY
但......还有另一个问题。由于timest
不是唯一的,因此挑选的50不是确定性的。因此,您可能希望更改为ORDER BY timest, id
或ORDER BY timest, char
。