Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/65.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 count()未与两个表JOIN和GROUP BY求和_Mysql_Sql_Join_Group By_Count - Fatal编程技术网

在标记方案中,Mysql count()未与两个表JOIN和GROUP BY求和

在标记方案中,Mysql count()未与两个表JOIN和GROUP BY求和,mysql,sql,join,group-by,count,Mysql,Sql,Join,Group By,Count,我有一个问题场景,这些问题都有与之相关联的标签,比如这里的StackOverflow。我想列出与某个问题相关联的所有标记,以及每个标记的计数,以说明其他问题使用/引用同一标记的次数 标签表:标签id、标签名称标签名称是唯一的 标记交叉引用表:标记id、问题id标记id引用标记表中的标记id,以及问题表中的问题id 问题表:问题id,问题 我的代码列出了与特定问题id关联的所有标记,但每个标记的总使用量的计数/数量始终为1,但应该是不同的总数 $question_id = 268; $sql =

我有一个问题场景,这些问题都有与之相关联的标签,比如这里的StackOverflow。我想列出与某个问题相关联的所有标记,以及每个标记的计数,以说明其他问题使用/引用同一标记的次数

标签表:标签id、标签名称标签名称是唯一的

标记交叉引用表:标记id、问题id标记id引用标记表中的标记id,以及问题表中的问题id

问题表:问题id,问题

我的代码列出了与特定问题id关联的所有标记,但每个标记的总使用量的计数/数量始终为1,但应该是不同的总数

$question_id = 268;
$sql = 'SELECT tags.tag_id, tag_name, count(tags.tag_id) AS num
        FROM tags LEFT JOIN tags_x 
        ON tags.tag_id = tags_x.tag_id 
        WHERE tags_x.question_id = ? 
        GROUP BY tags.tag_name';    
$stmt = $db->prepare($sql);
$stmt->execute([$question_id]); 
$result = $stmt->fetchAll(pdo::FETCH_ASSOC);
$out = '';
foreach($result as $row){
    $tag_id = $row['tag_id'];
    $tag_name = $row['tag_name'];
    $num = $row['num'];//count of all items referencing same tagname
    echo $tag_id.' - '.$tag_name.' - '.$num.'<br>';
}
当您在SELECT子句中包含tags.tag_id时,MySql将隐式地将其作为GROUP BY的一部分。这违反了ansi标准,顺便说一句,该标准根本不允许此查询

也许你想要counttags\u x.tag\u id


一个选项使用相关子查询来计算每个标记的问题数。我希望有更好的效率,因为它避免了外部聚合的需要:

select 
    t.tag_id, 
    t.tag_name, 
    (select count(*) from tags_x tx1 where tx1.tag_id = t.tag_id) no_questions
from tags t
inner join tags_x tx on tx.tag_id = t.tag_id
where tx.question_id = ? 
这将为您提供每个标签的问题总数。如果要计算除当前问题之外的其他问题的计数,可以从结果中减去1,或优化子查询的where条件:

select 
    t.tag_id, 
    t.tag_name, 
    (select count(*) from tags_x tx1 where tx1.tag_id = t.tag_id and tx1.question_id <> tx.question_id) no_questions
from tags t
inner join tags_x tx on tx.tag_id = t.tag_id
where tx.question_id = ? 
我认为我们需要两个对tag_x交叉引用表的引用,一个用于获取与我们的问题相关的标记,另一个用于获取对同一标记的所有引用

要返回标记名,我们需要一个到标记表的联接

大概是这样的:

SELECT t.tag_name
     , t.tag_id
     , COUNT(c.tag_id) AS cnt_references
  FROM tags_x q
  JOIN tags_x c
    ON c.tag_id = t.tag_id
  JOIN tags 
    ON t.tag_id = q.tag_id
 WHERE q.question_id = ?
 GROUP
    BY t.tag_name
     , t.tag_id
 ORDER
    BY t.tag_name
     , t.tag_id
SELECT q.tag_id
     , COUNT(c.tag_id) AS cnt_references
  FROM tags_x q
  JOIN tags_x c
    ON c.tag_id = t.tag_id
 WHERE q.question_id = ?
 GROUP
    BY q.tag_id
 ORDER
    BY q.tag_id
如果不需要返回tag_name,可以避免连接到tag表,只需执行以下操作:

SELECT t.tag_name
     , t.tag_id
     , COUNT(c.tag_id) AS cnt_references
  FROM tags_x q
  JOIN tags_x c
    ON c.tag_id = t.tag_id
  JOIN tags 
    ON t.tag_id = q.tag_id
 WHERE q.question_id = ?
 GROUP
    BY t.tag_name
     , t.tag_id
 ORDER
    BY t.tag_name
     , t.tag_id
SELECT q.tag_id
     , COUNT(c.tag_id) AS cnt_references
  FROM tags_x q
  JOIN tags_x c
    ON c.tag_id = t.tag_id
 WHERE q.question_id = ?
 GROUP
    BY q.tag_id
 ORDER
    BY q.tag_id
在内联视图中这样做可能会更快,稍后再连接到标记表。这将给出与第一个查询相同的结果

SELECT t.tag_name
     , t.tag_id
     , r.cnt_references
  FROM ( -- inline view to count references, one row per tag_id
         SELECT q.tag_id
              , COUNT(c.tag_id) AS cnt_references
           FROM tags_x q
           JOIN tags_x c
             ON c.tag_id = t.tag_id
          WHERE q.question_id = ?
          GROUP
             BY q.tag_id
       ) r
  JOIN tags t
    ON t.tag_id = r.tag_id
 ORDER
    BY t.tag_name
     , t.tag_id

尝试了上面的代码修改,得到了同样的结果。顶级代码工作得非常好!子查询-不知道您可以这样做!非常感谢你!