从两个查询中获取数据作为一个

时间:2016-09-10 15:53:30

标签: php sql pdo inner-join

这是图片类型的网页

我想要返回的是这样的字符串: nameOfTag(numberOfUnratedElements)

我使用的系统用户只知道图像的文件名,其余的存储在两个表中。

表格信息

table_name = images

  • id(int)primaryKey
  • filename(varchar255)unique
  • pick(tinyint)
  • 拒绝(tinyint)

table_name = image_tags

  • id(int)primaryKey
  • filename(varchar255)
  • tag_name(varchar255)

功能

程序应该从用户获取图像的文件名,并获取与该文件名相关联的所有标签。之后,程序应返回返回的每个标签中未评级(pick = FALSE AND reject = FALSE)图像的数量。

代码

截至目前,我正在使用循环来实现这一目标。 (“$ fname”是图像的文件名,格式为{filename}。{extension})

$query = $pdo->prepare("SELECT image_tags.tag_name, images.filename FROM image_tags JOIN images ON image_tags.filename = images.filename WHERE images.filename = ? ORDER BY image_tags.tag_name");
$query->bindValue(1, $fname);
$query->execute();
foreach($query->fetchAll() as $tag){
    $query = $pdo->prepare("SELECT count(*) as total, image_tags.tag_name, images.filename, images.pick, images.reject FROM image_tags JOIN images ON image_tags.filename = images.filename WHERE image_tags.tag_name = ? AND images.pick = FALSE AND images.reject = FALSE");
    $query->bindValue(1, $tag['tag_name']);
    $query->execute();
    print '<span style="display: block"><a style="display: inline-block" href=tag.php?tag=' . $tag['tag_name'] . '>' . $tag['tag_name'] . ' (' . $query->fetch()['total'] . ')</a></span>';
}

问题

我的问题是,如果有一种方法可以在不使用循环的情况下实现此目的,或者只使用一个查询?

1 个答案:

答案 0 :(得分:0)

您可以使用更多联接来执行此操作:

SELECT it.tag_name, i.filename, COUNT(i2.filename) as total,
       GROUP_CONCAT(i2.filename) as filenames
FROM image_tags it JOIN
     images i
     ON it.filename = i.filename LEFT JOIN
     image_tags it2
     ON it2.tag_name = it.tag_name LEFT JOIN
     images i2
     ON it2.filename = i2.filename AND
        i2.pick = FALSE AND i2.reject = FALSE
WHERE i.filename = ?
GROUP BY it.tag_name, i.filename
ORDER BY it.tag_name;

请注意,filenames是文件名的连接列表。我不确定是否需要它,它可能超过group_concat()(1024字节)的默认长度。

嗯,我想你可以简化你的第一个查询,因此这个查询可以:

SELECT it.tag_name, it.filename, COUNT(i2.filename) as total,
       GROUP_CONCAT(i2.filename) as filenames
FROM image_tags it LEFT JOIN
     image_tags it2
     ON it2.tag_name = it.tag_name LEFT JOIN
     images i2
     ON it2.filename = i2.filename AND
        i2.pick = FALSE AND i2.reject = FALSE
WHERE it.filename = ?
GROUP BY it.tag_name, i.filename
ORDER BY it.tag_name;

不需要第一个images引用,因为所有需要的数据都在image_tags中。