MySQL-是否可以合并选择查询,因此不必在while循环中执行?

时间:2019-11-06 16:50:10

标签: php mysql loops

所以我有一个查询,它将获取有关不可见项的匹配行的所有信息。

现在在while循环内部,我不得不使用选择计数查询来计算每个用户拥有多少不可见的项目,如果循环中有太多结果,则需要花费太多时间。

有没有一种方法可以查询它而不在while循环内运行选择查询?

例如:

SELECT  categories.name, 
        quality.name, 
        users.regdate,
        categories.name,
        items.name, 
        items.visible,
        items.owner,
        users.username
        FROM items
        LEFT JOIN users ON items.owner = users.id 
        LEFT JOIN categories ON items.category = categories.id 
        LEFT JOIN quality on items.category_quality = quality.id
        WHERE items.visible = 'no'

现在进入while循环以获取项目数,我不得不查询

while($row = mysqli_fetch_assoc($sql))
{
$all_items_by_user = "SELECT COUNT(items.name)
FROM items
WHERE items.owner = ".$row['owner']."";

$visible_items_by_user = "SELECT COUNT(items.name)
FROM items
WHERE items.owner = ".$row['owner']." AND items.visible = 'yes'";

// rest of code here.
// when there are 200 items in loop executing time goes crazy 
// (6+ secs, where with 1 item it's around 0.05)
}

编辑示例:

有人要求看看最终的代码是什么,我会尽力而为。

忽略左联接,因为这不是相对的,我只是从整个查询中添加了这些联接。

Id | item name | owner | Visible
1 | Item 1 | 2 | no
2 | Item 2 | 2 | yes
3 | Item 3 | 2 | no
4 | Item 4 | 2 | no
5 | Item 5 | 2 | no
6 | Item 6 | 3 | no
7 | Item 7 | 3 | no
8 | Item 8 | 3 | no
9 | Item 9 | 4 | no
10 | Item 10 | 4 | no

在每个用户的while循环中,它应该计算用户拥有多少行。

例如: 用户2总共拥有5行,隐藏了4行,($ all_items_by_user将计算所有内容,而$ visible_items_by_user将仅计算1) 用户3拥有3行, 用户4拥有2行。

如何对每个用户的项目进行计数,因为如果我在while循环之外进行操作,它将仅对第一个用户计数,而不对每个用户计数。

最终结果应该是

while($row = mysqli_fetch_assoc($sql))
{
$all_items_by_user = "SELECT COUNT(items.name)
FROM items
WHERE items.owner = ".$row['owner']."";

$visible_items_by_user = "SELECT COUNT(items.name)
FROM items
WHERE items.owner = ".$row['owner']." AND items.visible = 'yes'";

echo $row['owner'] . "(Visible items: number | All items: number";
// Output: 2 (Visible items: 1 | All items: 5)
}

2 个答案:

答案 0 :(得分:0)

您可以避免使用合并结果子查询的联接的循环查询

SELECT  categories.name, 
        quality.name, 
        users.regdate,
        categories.name,
        items.name, 
        items.visible,
        items.owner,
        users.username,
        ifnull(t.count_name,0), 
        ifnull(t.count_visible_name,0)
        FROM items
        LEFT JOIN users ON items.owner = users.id 
        LEFT JOIN categories ON items.category = categories.id 
        LEFT JOIN quality on items.category_quality = quality.id 
        LEFT JOIN  (
          select items.owner
            , COUNT(items.name) count_name
            , sum( case when items.visible = 'yes' AND item.name is not null
                then 1 else 0 end) count_visible_name
          from items 
          group by items.owner

        ) t on t.owner = items.owner 

确保您具有正确的综合索引

 on table  items column(owner, category, category_quality)

答案 1 :(得分:0)

这假设您关心每个用户的计数,并且关心任何项目的特定信息

SELECT items.owner,
    COUNT(items.name) AS itemCount, 
    SUM( CASE WHEN items.visible = 'yes' AND item.name IS NOT NULL
            THEN 1 ELSE 0 END) AS visibleCount
    FROM items 
    GROUP BY items.owner

然后,您只需遍历每一行,即可为您提供该用户,该用户的总计数以及该用户的可见计数。

DEMO