3

「犬」タグがつけられた記事がたくさんあります。「猫」という新しいタグを付けました。「犬」のタグが付いている記事に「猫」のタグをつけたいです。いくつかの記事には両方のタグが付いています。これらを「猫」で再タグ付けしたくありません。

つまり、記事に「犬」タグがあり、「猫」タグがまだない場合、「猫」タグを追加したいということです。これが私が書いたスクリプトです:

<?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 を含めることはできませんが、1 つの大きな SQL クエリにする必要があります。これを行う方法?

4

5 に答える 5

0

最初にテーブルを変更し、(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)";
于 2012-08-17T19:17:28.153 に答える
0

このクエリを試してください。私はこれをテストしていません。しかし、これはうまくいくと思います。

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')
)
于 2012-08-17T18:22:29.597 に答える
0

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')

そのようなことを試みる前にバックアップを作成してください;)

于 2012-08-17T17:23:46.477 に答える
0

次のクエリは、猫 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
于 2012-08-17T17:19:46.223 に答える
0

同じテーブルからのデータの選択に依存するデータを挿入する必要があるため、1 つのクエリでこれを行うことはできません。で定義された一意のキーがあると仮定すると、取得できる最も近いものは次のようになります(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 マネージャー ツールに貼り付けると、機能するはずです。

于 2012-08-17T17:22:47.363 に答える