0

特定の条件が満たされた場合、テーブル(以下に表示)が新しい挿入を取得したときに行を自動的に削除したいと思います。

いつ:

  • 同じ「user_id」を持つ同じ「フィールド」を参照する行があります
  • それらの「フィールド」、「表示」、および「検索」列は同じです

単純に、行が重複する場合('group_id'列を除く)、null以外の'group_id'を削除する必要があります。そうでない場合は、行を更新または挿入する必要があります。

これをmysqlで設定する方法はありますか(「ONDUPLICATE do stuff」の精神で、一意のキーなどと組み合わせて)、またはphpで明示的にチェックする必要がありますか(複数のクエリを使用)?

追加情報:すべての可能な「フィールド」に対してNULLの「group_id」を含む行が常に存在する必要があります(他の場所で定義された限定されたセットがあります)。一方、null以外の'group_id'を持つものはない場合があります。

CREATE TABLE `Views` (
`user_id` SMALLINT(5) UNSIGNED NOT NULL,
`db` ENUM('db_a','db_b') NOT NULL COLLATE 'utf8_swedish_ci',
`field` VARCHAR(40) NOT NULL COLLATE 'utf8_swedish_ci',
`display` TINYINT(1) UNSIGNED NOT NULL,
`search` TINYINT(1) UNSIGNED NOT NULL,
`group_id` SMALLINT(6) UNSIGNED NULL DEFAULT NULL,
UNIQUE INDEX `user_id` (`field`, `db`, `user_id`),
INDEX `Views_ibfk_1` (`user_id`),
INDEX `group_id` (`group_id`),
CONSTRAINT `Views_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `User` (`id`) ON
UPDATE CASCADE ON DELETE CASCADE
)
COLLATE='utf8_swedish_ci'
ENGINE=InnoDB;
4

3 に答える 3

2

論理を修正する必要があると思います。別の行を削除するためだけに行を挿入することは意味がありません。Group_ID重複する行のフィールドを挿入されているものに更新しないのはなぜですか?以下は、私がそれをどのように行うかについての大まかな考えです。

Nb私はMySQLで多くの作業を行っておらず、SQLFiddleで以下を実行することはできませんが、 MySQLドキュメントに基づいて理由を理解することはできません。おそらく、MySQLに精通している誰かが私を修正することができますか?

SET @User_ID = 1;
SET @db = 'db_a';
SET @Field = 'Field';
SET @Display = 1;
SET @Search = 1;
SET @Group_ID = 1;

IF EXISTS
    (   SELECT  1
        FROM    Views
        WHERE   User_ID = @User_ID
        AND     DB = @DB
        AND     Field = @Field
        AND     Group_ID IS NOT NULL
    ) 
    THEN
        UPDATE  Views
        SET     Group_ID = @Group_ID,
                Display = @Display,
                Search = @Search
        WHERE   User_ID = @User_ID
        AND     DB = @DB
        AND     Field = @Field
        AND     Group_ID IS NOT NULL
ELSE
        INSERT INTO Views (User_ID, DB, Field, Display, Search, Group_ID)
        VALUES (@User_ID, @DB, @Field, @Display, @Search, @Group_ID)
END IF;

または(そして私の好みの解決策)、タイムスタンプフィールドをテーブルに追加し、次のようにビューを作成します。

SELECT  v.User_ID, v.DB, v.Field, v.Display, v.Search, v.Group_ID
FROM    Views v
        INNER JOIN
        (   SELECT  User_ID, DB, Field, MAX(CreatedDate) AS CreatedDate
            FROM    Views
            WHERE   Group_ID IS NOT NULL
            GROUP BY User_ID, DB, Field
        ) MaxView
            ON MaxView.User_ID = v.User_ID
            AND MaxView.DB = v.DB
            AND MaxView.Field = v.Field
            AND MaxView.CreatedDate = v.CreatedDate
WHERE    v.Group_ID IS NOT NULL
UNION ALL
SELECT  v.User_ID, v.DB, v.Field, v.Display, v.Search, v.Group_ID
FROM    Views v
WHERE   v.Group_ID IS NULL

これにより、一意のレコードを表示できる必要性を損なうことなく、データへの変更を適切に追跡できます。

于 2012-05-24T11:11:49.900 に答える
0

あなたの質問は理解するのがあまり良くないので、これがあなたが望むものであるかどうかはわかりません:

DELETE FROM Views WHERE # delete from the table views
  group_id IS NOT NULL AND  # first condition delete only rows with not null group_id
  (SELECT count(*) as tot FROM Views GROUP BY group_id) = 1 # second condition count the difference in group id

それがあなたが望むものでない場合は、あなたの質問をより詳細に更新してください...

于 2012-05-24T08:05:46.867 に答える
0

group_id!='NUll'であるビューからgroup_idを削除します

于 2012-05-24T07:58:35.157 に答える