mysql查询:选择LastTest,其中不存在另一个包含N的行
很抱歉,关于标题,我甚至不知道如何描述这一点,这使得搜索解决方案变得更加困难 我有一张有很多答案的表格:mysql查询:选择LastTest,其中不存在另一个包含N的行,sql,mysql,Sql,Mysql,很抱歉,关于标题,我甚至不知道如何描述这一点,这使得搜索解决方案变得更加困难 我有一张有很多答案的表格: CREATE TABLE `answers` ( `a_id` int(11) NOT NULL auto_increment, `p_id` int(11) NOT NULL default '0', `q_id` int(11) NOT NULL default '0', `user_id` int(11) NOT NULL default '0', `correct
CREATE TABLE `answers` (
`a_id` int(11) NOT NULL auto_increment,
`p_id` int(11) NOT NULL default '0',
`q_id` int(11) NOT NULL default '0',
`user_id` int(11) NOT NULL default '0',
`correct` int(1) NOT NULL default '0',
`timestamp` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
PRIMARY KEY (`a_id`)
) ;
我需要从特定的用户id和p_id中选择一个q_id,其中correct=0,但仅当同一用户id和p_id的correct字段中最近的一行不是1时
我可以按id分组,但不确定如何消除顶部正确的分组!=0
提前谢谢。我在这里找到了许多有用的答案,我期待着尽我所能做出贡献
编辑:当前查询保持不变,但执行需要6秒:
从你们的两个答案中,我得到了一个有效的查询,但需要6秒才能执行
SELECT a.q_id FROM answers a
JOIN (SELECT b.q_id, MAX(b.a_id) as a_id, b.correct
FROM answers b
WHERE b.correct = 1
AND b.user_id = 1
AND b.p_id = 22
GROUP BY b.q_id) c ON a.q_id = c.q_id
AND a.a_id > c.a_id
WHERE a.correct = 0
AND a.user_id = 1
AND a.p_id = 22
LIMIT 1
如果没有加入,他们需要0.26秒。还有0.45秒的执行时间我如何才能提高效率
如果上一个correct=1行不存在,是否有其他方法选择最近的correct=0行
谢谢你的帮助 使用时间戳信息获取最新信息。您可以根据时间对记录进行排序。因为您有一个自动递增字段a\u id,所以可以使用它查找最新的条目。时间戳计算比主键排序慢
SELECT a.a_id, a.q_id, a.user_id, a.p_id, a.correct, c.correct
FROM answers a
JOIN (SELECT b.p_id, b.user_id, b.correct
FROM answers b
ORDER BY a_id DESC
LIMIT 1) c
ON (a.p_id = c.p_id
AND a.user_id = c.user_id)
WHERE c.correct != '1'
AND a.correct = '0'
AND a.user_id = '1234'
AND a.p_id = '5678'
ORDER BY a.a_id DESC
LIMIT 1;
如果不想限制结果的数量,请删除最后两行代码。这是我在这些情况下几乎总是使用的方法。它符合ANSI标准,在MS SQL Server中,性能通常比使用子查询要好得多。不过,我无法谈论MySQL的性能:
SELECT
A1.q_id
FROM
Answers A1
LEFT OUTER JOIN Answers A2 ON
A2.p_id = A1.p_id AND
A2.user_id = A1.user_id AND
A2.timestamp > A1.timestamp AND
A2.correct = 1
WHERE
A1.p_id = 22 AND
A1.user_id = 1 AND
A1.correct = 0
A2.a_id IS NULL -- This can only happen if no rows were found matching the JOIN criteria
顺便说一句,如果你想要最新的,那么你应该看时间戳,而不是a_id。虽然插入时几乎总是这样,至少数字是基于插入的时间顺序的,但通常不能保证。MS SQL中的情况绝对如此,我非常确定MySQL中也是如此,因为事务和可能的回滚会影响IDs。此查询似乎工作得最好。这是我编辑过的答案,通过订购a.a_id更新,并限制返回一个
SELECT a.q_id
FROM user_q_answers a
JOIN (SELECT b.user_id,
b.popling_id,
b.q_id,
MAX(b.a_id) as a_id
FROM user_q_answers b
WHERE b.correct = 1
GROUP BY b.q_id, b.user_id) c ON a.q_id = c.q_id
AND a.user_id = c.user_id
AND a.a_id > c.a_id
WHERE a.correct = 0
AND a.user_id = 101
AND a.popling_id = 170
ORDER BY a.a_id DESC
LIMIT 1
非常感谢OMG Ponies和Nirmal帮助我度过这一难关。很抱歉,如果回答我自己的问题是糟糕的形式在这里,但我组成了我的查询的基础上,我学到了你们两个
再次感谢 请看我的答案,让我知道这是否能解决问题。@robr:正确的答案呢!=1/正确!=0条件,以及这些记录之间的时间戳关系…是否可以更新旧行,是否应假定为最近的行?确认。我怀疑这个问题让我无从下手。我现在正努力实现你的目标。对不起,天哪,你的问题太离谱了@robr:请参阅我更新的答案-这是相对较小的更改,但它们使查询更加方便。如果我想将user_id和p_id指定为硬编码值,它们是否会在和a.correct='0'行之后,然后连接的查询引用它们?另外,它看起来像ORDER BY a_id DESC需要一个别名:b.a_id。但是我仍然收到错误“每个派生表都必须有自己的别名”,谢谢您的帮助!看起来我在select语句和派生表的别名中遗漏了很多列。我已经更正了我的答案。你可以试着让我知道。是的。必须在a.correct='0'之后指定它们。我在回答中加了一句。您可以检查它们。@Nirmal:除了时间戳列是一个日期数据类型外,其他所有内容都是整数-为什么您要使用SQL字符串表示法,使用单引号,对正确的、用户id等进行比较?!子查询只返回一行,与where子句无关。谢谢Tom H。我将进一步研究此查询和时间戳问题。我是根据比时间戳快的评论自动递增排序的。