选择N行的唯一记录限制

时间:2014-10-31 14:29:42

标签: mysql

我有如下所示的数据库记录,

id  | dataId    | value
1   |    1      |   xxx 
2   |    1      |   xx1
3   |    1      |   xx2
4   |    1      |   xx1
5   |    2      |   yyy
6   |    2      |   yy1
7   |    2      |   yy2 
8   |    1      |   zzz  
9   |    2      |   yy3  

我想要的结果将是这样的

id  | dataId    | value
8   |    1      |   zzz
4   |    1      |   xx1
3   |    1      |   xx2
9   |    2      |   yy3
7   |    2      |   yy2
6   |    2      |   yy1

我想为每个dataId选择N个最新id,其中N在这种情况下为3

提前谢谢。

4 个答案:

答案 0 :(得分:1)

  DROP TABLE IF EXISTS my_table;

  CREATE TABLE my_table
  (id  INT NOT NULL AUTO_INCREMENT PRIMARY KEY
  ,dataId INT NOT NULL    
  ,value VARCHAR(12) NOT NULL
  );

  INSERT INTO my_table VALUES
  (1   ,1      ,'xxx'),
  (2   ,1      ,'xx1'),
  (3   ,1      ,'xx2'),
  (4   ,1      ,'xx1'),
  (5   ,2      ,'yyy'),
  (6   ,2      ,'yy1'),
  (7   ,2      ,'yy2'),
  (8   ,1      ,'zzz'),
  (9   ,2      ,'yy3'); 

  SELECT x.* 
    FROM my_table x 
    JOIN my_table y  
      ON y.dataid = x.dataid 
     AND y.id >= x.id 
   GROUP 
      BY dataid
       , id 
  HAVING COUNT(*) <= 3 
   ORDER 
      BY dataid
       , id DESC;
  +----+--------+-------+
  | id | dataId | value |
  +----+--------+-------+
  |  8 |      1 | zzz   |
  |  4 |      1 | xx1   |
  |  3 |      1 | xx2   |
  |  9 |      2 | yy3   |
  |  7 |      2 | yy2   |
  |  6 |      2 | yy1   |
  +----+--------+-------+
  6 rows in set (0.03 sec)

  mysql>

答案 1 :(得分:0)

在mysql中,这是通过两个关键字来完成的: 第一个是使用的DISTINCTSELECT DICTINCT column FROM table 这样,只从数据库返回完整的唯一行。

第二个关键字用于限制返回的记录数,称为LIMIT 并使用:SELECT x FROM y LIMIT number

在您的情况下,它将类似于SELECT DISTINCT * FROM table LIMIT 10

更多信息: http://dev.mysql.com/doc/refman/5.0/en/select.html

您可能希望按特定列对结果进行排序,以便从表中获取10个日期。

sidenote:distinct可以在特定列和完整行上工作,在他的示例中它仅在完整行上,使用mysql手册来了解更多信息。

答案 2 :(得分:0)

您是否尝试选择第一个不同的值&#39;? 如果是这样你可以做到

SELECT id, dataId, distinct(value), date
FROM table
ORDER BY date

答案 3 :(得分:0)

这是一个有趣的article,您可以参考从一组中获取选定数量的项目。它可以从this question找到。

要获取每个数据ID的最新3个ID,您可以使用此查询:

SELECT id, dataid, value, date
FROM myTable m
WHERE(
  SELECT COUNT(*) FROM myTable mt
  WHERE mt.dataid = m.dataid AND mt.id >= m.id
) <= 3;

简而言之,where子句中的子查询将过滤最大的id vlaues,并且可以将其限制为小于或等于3.请注意WHERE mt.dataid = m.dataid是用于对行进行分组的内容。

正如文章所暗示的,这不是最有效的方式,而是一种干净的写作方式。一种可能更有效的方法是单独在每个查询上使用UNION。有关更多信息,请参阅文章。它看起来像这样:

(SELECT * FROM myTable WHERE dataid = 1 ORDER BY id DESC LIMIT 3)
UNION ALL
(SELECT * FROM myTable WHERE dataid = 2 ORDER BY id DESC LIMIT 3)

这两个例子都是SQL Fiddle