Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/78.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 如何在一个查询中实现更干净、更好的SQL查询?_Mysql_Sql_Limit_Distinct_Greatest N Per Group - Fatal编程技术网

Mysql 如何在一个查询中实现更干净、更好的SQL查询?

Mysql 如何在一个查询中实现更干净、更好的SQL查询?,mysql,sql,limit,distinct,greatest-n-per-group,Mysql,Sql,Limit,Distinct,Greatest N Per Group,我有这样的想法: SELECT cars.brand, cars.id FROM cars WHERE cars.brand = 4 LIMIT 1; SELECT cars.brand, cars.id FROM cars WHERE cars.brand = 24 LIMIT 1; SELECT cars.brand, cars.id FROM cars WHERE cars.brand = 29 LIMIT 1; 如果有更多的查询,它将是非常长的。 如何以另一种方式,在一行中实现这一点?

我有这样的想法:

SELECT cars.brand, cars.id FROM cars WHERE cars.brand = 4 LIMIT 1;
SELECT cars.brand, cars.id FROM cars WHERE cars.brand = 24 LIMIT 1;
SELECT cars.brand, cars.id FROM cars WHERE cars.brand = 29 LIMIT 1;
如果有更多的查询,它将是非常长的。 如何以另一种方式,在一行中实现这一点?但对我来说重要的是速度。 cars.brand=X,限制X是一个变量,因此它可能会改变。

方法1:

SELECT cars.brand, cars.id FROM cars WHERE cars.brand IN(4, 24, 29) LIMIT 1;
方法2:


您担心必须一个接一个地发送如此多的查询,因此这将花费大量时间。您可以改为进行以下一个查询:

SELECT cars.brand, cars.id FROM cars WHERE cars.brand = 4 LIMIT 1
UNION ALL
SELECT cars.brand, cars.id FROM cars WHERE cars.brand = 24 LIMIT 1
UNION ALL
SELECT cars.brand, cars.id FROM cars WHERE cars.brand = 29 LIMIT 1;

由于您似乎并不关心为每个品牌返回哪个汽车id,只要每个品牌只有一个id,就可以使用MAX或MIN按品牌选择id分组:-

SELECT cars.brand, MAX(cars.id) AS id
FROM cars 
WHERE cars.brand IN(4, 24, 29) 
GROUP BY cars.brand;
假设您有有用的索引,这应该很快

如果你想要不同数量的限量车,你可以对它们进行排序,并使用一个变量为每辆车分配一个编号,然后去掉那些编号高于该编号的车。例如,将其限制为每项中的3项:-

SELECT sub0.brand, sub0.id, @ctr := IF(@brand = sub0.brand, @ctr:=@ctr+1, 1) AS brand_ctr, @brand := sub0.brand
FROM
(
    SELECT cars.brand, cars.id
    FROM cars 
    WHERE cars.brand IN(4, 24, 29) 
    ORDER BY cars.brand
) sub0
CROSS JOIN (SELECT @ctr := 1, @brand := 0) sub1
HAVING brand_ctr <= 3

根据品牌的数量,这不是非常有效,但是创建动态SQL非常容易,您只需要in子句中的ID来设置SQL,而不是建立大量的联合声明。

如果我理解您的问题是正确的,那么这就是您的答案。因此,您只需要一个声明,而不是n个具有不同品牌甚至可能不同限制的声明?具体原因是什么?因为像这样的100个查询不是最好的方式,因为100个单查询而不是一个大查询太慢了?好的,我会发布一个答案。谢谢,但如果我只想限制ID 24的限制2?在这种情况下会发生什么。如果$id=24{LIMIT 2}?。。。只是像这样,但不太好,我觉得你一直在改变问题。如果您想要使用不同id的不同限制,您可以扩展$ids数组,为每个id指定一个限制,而不是单独的限制变量,并像汽车一样使用它。brand=$id['id']limit$id['limit']
SELECT cars.brand, cars.id FROM cars WHERE cars.brand = 4 LIMIT 1
UNION ALL
SELECT cars.brand, cars.id FROM cars WHERE cars.brand = 24 LIMIT 1
UNION ALL
SELECT cars.brand, cars.id FROM cars WHERE cars.brand = 29 LIMIT 1;
SELECT cars.brand, MAX(cars.id) AS id
FROM cars 
WHERE cars.brand IN(4, 24, 29) 
GROUP BY cars.brand;
SELECT sub0.brand, sub0.id, @ctr := IF(@brand = sub0.brand, @ctr:=@ctr+1, 1) AS brand_ctr, @brand := sub0.brand
FROM
(
    SELECT cars.brand, cars.id
    FROM cars 
    WHERE cars.brand IN(4, 24, 29) 
    ORDER BY cars.brand
) sub0
CROSS JOIN (SELECT @ctr := 1, @brand := 0) sub1
HAVING brand_ctr <= 3