繁体   English   中英

如何将所有这些MySQL查询合并为一个?

[英]How to combine all these MySQL queries into one?

我有很多文章用标签“dog”标记。 我有一个名为“cat”的新标签。 我想在所有已经标记为“dog”的文章中添加标签“cat”。 一些文章都有两个标签。 我不想用“猫”来重复这些。

换句话说,如果一篇文章的标签为“dog”且还没有标签“cat”,我想在其中添加标签“cat”。 这是我写的脚本:

<?php 

    # Get "cat" tag id
    $sql = "SELECT `id`
            FROM tags
            WHERE name = 'cat'
            LIMIT 1";

    $cat_tag = mysql_fetch_assoc(mysql_query($sql));

    # Get "dog" tag id
    $sql = "SELECT `id`
            FROM tags
            WHERE name = 'dog'
            LIMIT 1";

    $dog_tag = mysql_fetch_assoc(mysql_query($sql));

    ######################################

    # Get all nodes tagged with "dog"   
    $sql = "SELECT `node_id`
            FROM node_tags
            WHERE `tag_id` = '" . $dog['id'] . "'";

    $query = mysql_query($sql);
    while($row = mysql_fetch_assoc($query)) {

        # Check to see if current node has "cat" tag already    
        $sql = "SELECT COUNT(*)
                FROM node_tags
                WHERE `node_id` = '" . $row['node_id'] . "'         
                AND `tag_id` = '" . $cat['id'] . "'";


        $check_already_exists = mysql_fetch_assoc(mysql_query($sql));

        # If node doesn't already have "cat" tag, then add it
        if($check_already_exists == '0') {
            $sql = "INSERT INTO `node_tags`(node_id, tag_id) 
                    VALUES('" . $row['node_id'] . "', '" . $cat['id'] . "')";
            mysql_query($sql);
        }
    }

?>

我希望能够直接从我的MySQL管理器工具运行它。 所以它不能有任何PHP,但应该是一个大的SQL查询。 这个怎么做?

以下查询获取没有cat id的所有“狗”。 然后将它们插入表中:

insert into node_tags(node_id, tag_id)
    SELECT id, $cat['id']
    FROM tags t join
         node_tags nt
         on t.node_id = nt.node_id
    WHERE t.name = 'dog'
    group by id
    having max(case when tag_id = $cat['id'] then 1 else 0 end) = 0

您不能在一个查询中执行此操作,因为您需要插入依赖于从同一个表中选择数据的数据。 假设您在(node_id,tag_id)上定义了唯一键,那么您可以得到的最接近的是这样的:

CREATE TEMPORARY TABLE `tmp` (`node_id` TEXT, `tag_id` TEXT); # Choose better column types if possible
INSERT INTO `tmp` SELECT `node_id`, `tag_id` FROM `node_tags`;
SET @id_cat = (SELECT `id` FROM `tags` WHERE `name`='cat'),
    @id_dog = (SELECT `id` FROM `tags` WHERE `name`='dog');
INSERT IGNORE INTO `node_tags` (`node_id`, `tag_id`)
  SELECT `node_id`, @id_cat FROM `tmp` WHERE `tag_id`=@id_dog
  UNION
  SELECT `node_id`, @id_dog FROM `tmp` WHERE `tag_id`=@id_cat;
DROP TABLE `tmp`;

您可以将其粘贴到MySQL管理器工具中,它应该可以工作。

您可以基于select子句创建插入:

INSERT INTO node_tags (node_id, tag_id)
SELECT node_id, (SELECT MAX(id) FROM tags WHERE name = 'cat') 
FROM node_tags 
WHERE tag_id = (SELECT MAX(id) FORM tags WHERE name = 'dog')

在尝试这样的事情之前做一个备份;)

试试这个查询。 我没有测试过这个。 但我认为这会奏效。

INSERT into node_tags(node_id, tag_id)
( SELECT node_id, tag_id
 FROM node_tags nt , tags t
 where t.id = nt.tag_id AND t.name = 'dog' 
 AND nt.node_id NOT IN (SELECT t1.id FROM node_tags nt1, tags t1
 where nt1.node_id = nt.node_id  AND t1.id = nt1.tag_id AND t1.name = 'cat')
)

首先更改你的表并使(node_id和tag_id)一起使用UNIQUE,因为这就是你需要的东西。

ALTER TABLE `node_tags` ADD UNIQUE (`node_id`,`tag_id`);

这是你的查询:

$sql = "INSERT IGNORE INTO `node_tags`  
        SELECT (SELECT `node_id` FROM node_tags WHERE EXISTS (SELECT tags.* FROM tags WHERE node_tags.`tag_id` = tags.`id` AND tags.name = 'dog') LIMIT 1),
               (SELECT `id` FROM tags WHERE name = 'cat' LIMIT 1)";

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM