mysql查询:选择Lastest,其中N行不存在

时间:2009-12-17 03:36:12

标签: 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` int(1) NOT NULL default '0',
  `timestamp` timestamp NOT NULL default CURRENT_TIMESTAMP on update CURRENT_TIMESTAMP,
  PRIMARY KEY  (`a_id`)
) ;

我需要从特定q_iduser_id中选择p_id,其中正确= 0,但仅限于来自同一user_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秒。和.45秒执行如何提高效率?

是否有其他方法可以选择最近的正确= 0行,其中不存在prev correct = 1行?

感谢您的帮助!

4 个答案:

答案 0 :(得分:0)

使用时间戳信息获取最新信息。您可以根据时间订购记录。

答案 1 :(得分:0)

由于您有自动增量字段a_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;

如果您不想限制结果数量,请删除最后两行代码。

答案 2 :(得分:0)

这是我在这些情况下几乎总是使用的方法。它符合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中也是如此,因为事务和潜在的回滚影响了ID。

答案 3 :(得分:0)

此查询似乎效果最佳。这是我编辑的答案,通过订购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帮助我完成这项工作。很抱歉,在这里回答我自己的问题是不好的表格,但我根据我从你们那里学到的东西包含了我的查询。

再次感谢!!!