首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >MySQL:如何使用每个WHERE筛选器的限制执行查询

MySQL:如何使用每个WHERE筛选器的限制执行查询
EN

Stack Overflow用户
提问于 2018-02-02 05:08:53
回答 4查看 332关注 0票数 1

我需要做一个按ID过滤的查询,但我需要限制每个ID的结果。我不知道如何在一个查询中做到这一点,我只能用PHP循环每个ID,在每次迭代中执行一个查询,然后将结果合并在一起:

代码语言:javascript
运行
复制
$allResults = [];
$ids = [1, 2, 3, 4, 5];

foreach ($ids as $id) {

    $db->query("
        SELECT *
        FROM example_table
        WHERE example_id = $id
        ORDER BY rating DESC
        LIMIT 2
    ");
    $results = $db->getResults();

    $allResults = array_merge($allResults, $results);
}

上面做了我需要的,但是我如何在一个查询中做到这一点,而不是5个查询的循环呢?

我在找这样的东西:

代码语言:javascript
运行
复制
    SELECT *
    FROM example_table
    WHERE 
        example_id = 1 LIMIT 2 OR
        example_id = 2 LIMIT 2 OR
        example_id = 3 LIMIT 2 OR
        example_id = 4 LIMIT 2 OR
        example_id = 5 LIMIT 2
    ORDER BY rating DESC

显然,where子句中的限制抛出了一个错误,但您可以看到我试图实现的目的。感谢您的帮助。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2018-02-02 05:34:44

正如@Strawberry提到的,没有可验证的例子和数据很难给出正确的答案,但这就是查询可能的样子,因为mysql还不支持组排名函数。

代码语言:javascript
运行
复制
SELECT * FROM
(SELECT *, 
    @f_rank := IF(@f_rating = rating AND @f_id = id, @f_rank + 1, 1) AS rank, 
    @f_rating := rating,
    @f_id := id
FROM   example_table 
WHERE id IN (1, 2, 3, 4, 5)
ORDER  BY id, rating DESC) tmp_table
WHERE tmp_table.rank <= 2

您需要做的是对每个id的所有评分从1到n进行排序。然后选择前两个ids。

票数 2
EN

Stack Overflow用户

发布于 2018-02-02 05:54:26

您可以使用以下UNION查询:

代码语言:javascript
运行
复制
(SELECT * FROM example_table WHERE id = 1 ORDER BY rating DESC LIMIT 2)
UNION ALL
(SELECT * FROM example_table WHERE id = 2 ORDER BY rating DESC LIMIT 2)
UNION ALL
(SELECT * FROM example_table WHERE id = 3 ORDER BY rating DESC LIMIT 2)
UNION ALL
(SELECT * FROM example_table WHERE id = 4 ORDER BY rating DESC LIMIT 2)
UNION ALL
(SELECT * FROM example_table WHERE id = 5 ORDER BY rating DESC LIMIT 2)

以下是在PHP中创建它的一种方法:

代码语言:javascript
运行
复制
$ids = [1, 2, 3, 4, 5];

$sqlArray = array_map(function($id){
    $id = (int)$id;
    return "(SELECT * FROM example_table WHERE id = $id ORDER BY rating DESC LIMIT 2)";
}, $ids);

$sql = implode("\nUNION ALL\n", $sqlArray);

演示:http://rextester.com/GNDR46232

您还应该考虑使用占位符准备查询并绑定ids。因为我不知道$db的类是PDO方法:

代码语言:javascript
运行
复制
$ids = [1, 2, 3, 4, 5];

$sqlArray = array_map(function($id){
    return "(SELECT * FROM example_table WHERE id = ? ORDER BY rating DESC LIMIT 2)";
}, $ids);

$sql = implode("\nUNION ALL\n", $sqlArray);

$stmt = $db->prepare($sql);
$stmt->execute($ids);
$allResults = $stmt->fetchAll(PDO::FETCH_ASSOC);
票数 2
EN

Stack Overflow用户

发布于 2018-02-02 05:20:53

它比我想象的要复杂一点,但是你应该能够很容易地在PHP中以编程方式创建查询。您甚至不能对UNION进行直接限制,但您可以有效地对select执行select操作,并在最低级别设置限制。这是否比执行5个单独的查询效率更高还是个未知数。

代码语言:javascript
运行
复制
SELECT *
      FROM (SELECT *
            FROM example_table
            WHERE id = 1
            LIMIT 2) AS id1
      UNION
      SELECT *
      FROM (SELECT *
            FROM example_table
            WHERE id = 2
            LIMIT 2) AS id2
      UNION
      SELECT *
      FROM (SELECT *
            FROM example_table
            WHERE id = 3
            LIMIT 2) AS id3
      .... more UNIONS ....;
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48571748

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档