我的表格标记包含字段tag_id
和name
。我有一个联结表 tag_map ,其中包含字段tag_id
和vid_id
,用于将表标记连接到表视频(通过vid_id )。
当我为vid_id
插入新标记时,我删除了vid_id
的tag_map中的所有条目,如果tag_map
中只有一个条目我还想删除该条目表tags
中的标记用于防止ghost条目(标记没有相应tag_map条目的条目)。
问题是,我似乎无法准确地获得这个数。例如,如果我在tag_map
中有3个条目,每个条目在tags
中都有1个相应的标记,则每个标记的计数为1,0,0。我是否为此目的使用了错误的查询?
//find all tags for given vid_id
$sql = 'SELECT tag_map.*, tags2.name AS tag_name
FROM tag_map
INNER JOIN tags2 ON tags2.tag_id = tag_map.tag_id
INNER JOIN video ON video.vid_id = tag_map.vid_id
WHERE tag_map.vid_id=?';
$stmt_tags = $conn->prepare($sql);
$result=$stmt_tags->execute(array($vid_id));
while ($row = $stmt_tags->fetch(PDO::FETCH_ASSOC)) {
$tag_name=$row['tag_name'];
//for each tag check how many rows exist in tag_map COUNT IS NOT ACCURATE
$sql = 'SELECT *, COUNT(tags2.name) as cnt
FROM tag_map
JOIN tags2 ON tags2.tag_id = tag_map.tag_id
JOIN video ON video.vid_id = tag_map.vid_id
WHERE tags2.name=?';
$stmt_tags2 = $conn->prepare($sql);
$result=$stmt_tags2->execute(array($tag_name));
while ($row2 = $stmt_tags2->fetch(PDO::FETCH_ASSOC)) {
echo $cnt=$row2['cnt'];
}
if ($cnt==1){
$sql = "DELETE FROM tag_map WHERE vid_id = ?";
$stmt14 = $conn->prepare($sql);
$result=$stmt14->execute(array($vid_id));
$sql = "DELETE FROM tags2 WHERE tags2.name = ?";
$stmt14 = $conn->prepare($sql);
$result=$stmt14->execute(array($tag_name));
}
else {
$sql = "DELETE FROM tag_map WHERE vid_id = ?";
$stmt14 = $conn->prepare($sql);
$result=$stmt14->execute(array($vid_id));
}
}
编辑插入多对多
foreach($variable as $tag) {
$sql = 'SELECT *, COUNT(tags2.name) as cnt
FROM tag_map
JOIN tags2 ON tags2.tag_id = tag_map.tag_id
JOIN video ON video.vid_id = tag_map.vid_id
WHERE tags2.name=?';
$stmt_tags2 = $conn->prepare($sql);
$result=$stmt_tags2->execute(array($tag));
while ($row = $stmt_tags2->fetch(PDO::FETCH_ASSOC)) {
$cnt=$row['cnt'];
$exist_tag_id=$row['tag_id'];
}
$id=md5(uniqid());
$tag_id=md5(uniqid());
if ($cnt==0){
$sql="INSERT into tag_map (id,vid_id,tag_id) VALUES (?,?,?)";
$stmt16 = $conn->prepare($sql);
$result=$stmt16->execute(array($id,$vid_id,$tag_id));
$sql="INSERT into tags2 (tag_id,name) VALUES (?,?)";
$stmt16 = $conn->prepare($sql);
$result=$stmt16->execute(array($tag_id,trim($tag)));
}
else {
$sql="INSERT into tag_map (id,vid_id,tag_id) VALUES (?,?,?)";
$stmt16 = $conn->prepare($sql);
$result=$stmt16->execute(array($id,$vid_id,$exist_tag_id));
}
}
答案 0 :(得分:1)
你甚至不需要担心计数。从tag_map中删除然后:
DELETE t
FROM tags2 t
LEFT JOIN tag_map tm
ON t.tag_id = tm.tag_id
WHERE tm.tag_id IS NULL;
答案 1 :(得分:1)
难道你不能这样做吗?或者我错过了什么?
删除某个视频中的所有代码,然后删除tag_map表中没有相应值的代码。
DELETE FROM tag_map WHERE vid_id = <video_id>;
DELETE FROM tags t
WHERE NOT EXISTS (SELECT 1 FROM tag_map tm WHERE tm.tag_id = t.tag_id);
答案 2 :(得分:1)
在您的两个查询中,由于您只在vid_id上运行,因此不需要加入视频。只需专注于tags2和tag_map表。使用额外连接时,如果您没有该标记的视频条目,则可能会出现错误0。
此外,如果您想获取特定tag_id的计数,请执行以下操作:
SELECT COUNT(tm.tag_id) FROM tags2 t
LEFT OUTER JOIN tag_map ON tm.tag_id = t.tag_id
WHERE t.name = ?
执行外部联接,这样在tag_map中没有条目的条目时,您实际上会得到0的计数。
但是,我更喜欢实际的DELETE,就像上面检查存在的那样。