SQL技术问题:跨表选指定ID后行及宝可梦技能查询结果异常
问题1:如何从另一张表中选取某个特定ID之后的所有行?
这个需求得看具体的表关联逻辑,我给你两种常见场景的解决方案:
- 场景1:先从表A获取一个阈值ID,再筛选表B中大于该ID的行
比如你要从表A中拿到某条特定记录的ID,然后用这个ID作为分界点,选出表B里所有ID比它大的行。假设表A里有个user_id字段,你要找用户名为"Alice"的ID,然后选表B中ID大于这个值的所有行:
-- 先获取阈值ID,再筛选表B SELECT * FROM table_b WHERE id > (SELECT user_id FROM table_a WHERE username = 'Alice');
如果表A符合条件的记录有多个,你想取最大的那个ID作为阈值,就用MAX()函数:
SELECT * FROM table_b WHERE id > (SELECT MAX(user_id) FROM table_a WHERE username LIKE 'A%');
- 场景2:基于表关联,选取表B中关联表A特定记录之后的行
如果表B和表A是关联的(比如表B的a_id对应表A的id),你要找表B中,在表A某条记录对应的表B行之后的所有行(按表B的ID排序),可以用CTE来实现:
WITH target_b_row AS ( SELECT b.id FROM table_b b JOIN table_a a ON b.a_id = a.id WHERE a.some_column = 'target_value' ) SELECT * FROM table_b WHERE id > (SELECT id FROM target_b_row);
要是你想按其他顺序(比如创建时间)来定义“之后”,把上面的id换成对应的排序字段(比如create_time)就行。
问题2:查询宝可梦"bulbasaur"所有技能仅返回1条结果的排查与解决
咱们来分析你的SQL语句问题所在:
你写的语句里用了WHERE id=(SELECT move_id FROM ...),这里的=运算符要求后面的子查询只能返回单个值。但POKEMONS_MOVES表中,对应bulbasaur的pokemon_id肯定有多个move_id记录(毕竟它有9个技能),SQLite遇到这种情况只会取子查询返回的第一个move_id,所以你只得到了1条结果。
解决这个问题有两种常用方法:
方法1:把=换成IN
IN运算符可以匹配子查询返回的多个值,修改后的SQL如下:
SELECT name, power, pp, accuracy FROM MOVES WHERE id IN ( SELECT move_id FROM POKEMONS_MOVES WHERE pokemon_id = ( SELECT id FROM POKEMONS WHERE name = "bulbasaur" ) );
方法2:使用JOIN关联三张表(更推荐)
用JOIN直接关联三张表,逻辑更清晰,可读性更强,在数据量较大时性能也更优:
SELECT m.name, m.power, m.pp, m.accuracy FROM MOVES m JOIN POKEMONS_MOVES pm ON m.id = pm.move_id JOIN POKEMONS p ON pm.pokemon_id = p.id WHERE p.name = "bulbasaur";
这两种方法都能返回bulbasaur的所有9个技能,你可以根据自己的习惯选择~
内容的提问来源于stack exchange,提问作者F.Bodelón
相关产品推荐
相关产品推荐

