MYSQL子查询中替代使用LIMIT关键字的方法

37

我有一个名为TEST的表格,包含以下列:

code_ver (VARCHAR)
suite (VARCHAR)
date (DATE)

现在我想选择10行,这十行的code_ver & code_ver NOT LIKE '%DevBld%'且按日期降序排序且具有不同的值。

因此我编写了以下查询:

select * 
  from test 
 where code_ver IN (select DISTINCT code_ver 
                      from test 
                     where code_ver NOT LIKE '%DevBld%' 
                     ORDER by date DESC LIMIT 10);

这个查询本来应该可以工作,但我的MySQL版本出现了问题:

这个版本的MySQL还不支持“LIMIT&IN/ALL/ANY/SOME子查询”

是否有人能够为我提供一个替代这个查询的方法?


请展示给我们样本数据以及您想要的结果。 - pilcrow
7个回答

71

在我看来,Layke提出的答案是不正确的。在子查询中使用limit的目的是使主查询仅在从子查询中获取的有限记录上运行。如果我们将limit放在外面,那么对于子查询来说就变得没有意义了。

由于mysql尚不支持在子查询中使用limit,因此您可以使用以下JOIN:

       
    SELECT * FROM test
    JOIN 
    (
        SELECT DISTINCT code_ver 
        FROM test 
        WHERE code_ver NOT LIKE '%DevBld%' 
        ORDER BY date DESC LIMIT 10
    ) d
    ON test.code_ver
    IN (d.code_ver)
    ORDER BY xyz;

5
为什么"(select DISTINCT code_ver from test where code_ver NOT LIKE %DevBld%' ORDER by date DESC LIMIT 10)"不被视为子查询,并且允许在其中使用LIMIT? - edeesan
1
如果我们将查询作为其他查询的派生数据源,例如问卷调查者输入的“select * from test where code_ver IN (select DISTINCT code_ver from test where code_ver NOT LIKE '%DevBld%' ORDER by date DESC LIMIT 10);”,那么我们称之为子查询。但是根据MySQL当前规则,子查询中不允许使用LIMIT,因此我建议使用JOIN来实现目的。 - aneetkukreja

41

你也可以使用同样的查询,只需在子查询之前再添加一个额外的 SELECT 层级即可。就是这样,它会起作用。

select * from test 
where code_ver IN (select * from (select DISTINCT code_ver 
                      from test 
                     where code_ver NOT LIKE '%DevBld%' 
                     ORDER by date DESC LIMIT 10) as t1);

2
谢谢,这个解决方案可行并值得采纳。 - Arthur Khazbs
1
非常简单,而且完美地运行。这个应该是被采纳的答案。 - S3DEV

8
将子查询放入派生表中:
   SELECT test.*
     FROM test
LEFT JOIN (SELECT DISTINCT code_ver
             FROM mastertest
            WHERE code_ver NOT LIKE '%DevBld%'
            ORDER BY `date` DESC
            LIMIT 10) d
    USING (code_ver)
    WHERE d.code_ver IS NOT NULL;

(当然,您也可以使用RIGHT JOIN,并且删除外部WHERE条件。)

我尝试了这个方法,但它仍然返回了大约84行数据,并且它们也不是唯一的... :( - Pi Horse
@sagarvikani,那我不明白你试图做什么。假设你执行了 CREATE TABLE t SELECT DISTINCT code_ver ... LIMIT 10,然后尝试使用 WHERE code_ver IN (SELECT code_ver FROM t) 进行原始查询。我预期您仍将获得 84 行数据。 - pilcrow
我刚刚执行了你上面写的查询。 - Pi Horse

0

可能有点晚了,但是你可以将子查询包装到另一个查询中,并从子查询中获取所有内容。

   SELECT * FROM tableWHERE id NOT IN 
    (SELECT * FROM 
        ( SELECT id FROM table LIMIT 0, 2) as SUBQUERY
    )

0

选择 * 从测试 其中 code_ver 在 ( 选择 code_ver,RANK() OVER (ORDER BY date DESC) AS rank_of_date 从测试 其中 code_ver 不像 '%DevBld%' ) 其中 rank_of_date <= 10 );


-2
select * from test t1, (select DISTINCT code_ver 
                      from test 
                     where code_ver NOT LIKE '%DevBld%' 
                     ORDER by date DESC LIMIT 10 ) as t2
where t1.code_ver=t2.code_ver

4
一些解释和格式可能有助于理解为什么你认为这个答案对这个问题有价值。 - Luuk

-14
你遇到的错误并不完全是因为MySQL的版本问题。我认为所有版本都支持它。你需要将LIMIT 10的位置改变,并将其放在“)”之后。如果这样做可以解决问题,请告诉我。我在我的电脑上运行了下面的代码,它可以正常工作。
例如:
SELECT * FROM test where name IN (
           SELECT DISTINCT name 
           FROM projects 
           WHERE name NOT LIKE "%DevBld%"  
           ORDER by date_created DESC
 ) LIMIT 10;

更新:请尝试下面的方法,这样顺序就可以正常工作:

 SELECT * FROM  automation.e2e_projects WHERE name IN (
       SELECT DISTINCT name 
       FROM automation.e2e_projects
       WHERE name NOT LIKE "%DevBld%"
 ) ORDER by date_created DESC LIMIT 10;

从SELECT *开始。第一行! - Sara
11
如果有多行与名称相关联,它就无效了,只会为“test”表显示10行。我认为这不是问题的正确解决方案。 - Shubham Baranwal
派生表的答案似乎更正确。 - Mladen Mihajlovic

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接