2

USERS次のフィールドを含むTABLEがあります_id name number_of_posts

そして私はPOSTS次のフィールドを含むTABLEを持っています_id user_id post_text

との関係はありません。つまりusers、1人のユーザーが多くの投稿を持っていますpostsone- to -many

問題は、テーブル内の投稿数を保持するようnumber_of_postsにテーブル内を更新する方法です。usersposts

アップデート

これらのテーブルには約数百のレコードがあり、トリガーを使用してnumber_of_postsを更新する方法はありません。

4

4 に答える 4

2

以下のサンプルスクリプトは、withテーブルを使用して両方usersを結合し、 usersテーブルの* _id *フィールドで使用して投稿数を取得することにより、ユーザーに関連付けられた投稿の数を取得する方法を示しています。postsLEFT OUTER JOINGROUP BY

SQL Fiddleでサンプルを表示するには、ここをクリックしてください。

クエリ:

CREATE TABLE users 
(
    _id     INT NOT NULL
  , name    VARCHAR(30) NOT NULL
);

CREATE TABLE posts 
(
    _id     INT NOT NULL
  , _userid INT NOT NULL
  , name    VARCHAR(30) NOT NULL
);

INSERT INTO users (_id, name) VALUES
  (1, 'user 1'),
  (2, 'user 2'),
  (3, 'user 3');

INSERT INTO posts (_id, _userid, name) VALUES
  (1, 1, 'post 1'),
  (2, 1, 'post 2'),
  (3, 2, 'post 3');

SELECT          u._id
            ,   u.name
            ,   COUNT(p._id) number_of_posts
FROM            users u
LEFT OUTER JOIN posts p
ON              u._id = p._userid
GROUP BY        u._id;

出力

_ID NAME    NUMBER_OF_POSTS
--- ------  ---------------
1   user 1         2
2   user 2         1
3   user 3         0
于 2012-04-29T14:58:33.057 に答える
1

これは、投稿テーブルのトリガーを使用して行うことができます。投稿が挿入されるたびに、usersテーブルのnumber_of_postsを更新します。

http://dev.mysql.com/doc/refman/5.6/en/triggers.htmlを参照してください

更新:完全に機能するソリューション

drop table if exists users;
create table users (  
   _id bigint unsigned auto_increment primary key,   
   name varchar(50) not null, 
   number_of_posts integer not null default 0
);

drop table if exists posts;
create table posts (  
   _id bigint unsigned auto_increment primary key,   
   user_id bigint unsigned not null, 
   post_text text
);

-- Populate with dummy data
insert into users (name) values ('Bob'), ('Sally');
insert into posts (user_id, post_text) 
    values (1, 'First!!'), (1, 'Second...'), 
           (2, 'Post 1'), (2, 'another post'), (2, 'more posts');

-- One-time update of users table
update users u
set u.number_of_posts = (      
  select count(0) from posts p
  where u._id = p.user_id      
);

-- trigger to keep post count up to date when future posts are made
drop trigger if exists trg_post_count;
delimiter $$

create trigger trg_post_count
after insert on posts
for each row 
begin
    select count(0) into @post_count 
    from posts
    where user_id = NEW.user_id;

    update users
    set number_of_posts = @post_count
    where _id = NEW.user_id;
end;
$$

delimiter ;

-- test trigger
insert into posts (user_id) values (2);
select * from users;
于 2012-04-29T14:43:25.437 に答える
1

1回限りの更新として、これを試してください。ただし、トリガーソリューションは、最新の状態に保つための適切なソリューションです。

UPDATE users AS u SET u.number_of posts = (SELECT COUNT(*) FROM posts AS p WHERE p.user_id=u.user_id)
于 2012-04-29T14:55:58.580 に答える
0

dwurfが示唆したように、フィールドを最新の状態に保つために、これをトリガーに入れることを強くお勧めします。しかし、私は彼に完全に同意しません。それは、更新のたびに増分する数値でなければならないということです。それは壊れやすく、エラーが発生しやすいです。次のクエリを使用して、各ユーザーの投稿数を正確に把握する必要があります。

update
  users
set 
  number_of_posts = ( 
    select
      count(0)
    from
      posts p
    where
      p.user_id = users.id
    )   
; 
于 2012-04-29T14:57:07.940 に答える