SQLノート、select countが0の疑惑について解決します
4026 ワード
SQLテーブルは次の2つあります.
クエリーstatus_dbのコンテンツの場合、ユーザの顔、名前、コメント数(コメントテーブルにsidがない場合は、このコメントを0と表す)を表示する必要があります.つまり、この場合は3つのテーブルを検索する必要があります.最初はこうしました
次は私が最初に書いたsql文です.
理想的にはcomment_numが0に等しい場合も表示すべきであるが、このような結果はすべての状態のコメント数が同じである.何が間違っているのかと思って、sql文を直して、簡略化してみました.
これでいいですが、コメント数が0のものは表示できません.これはなぜですか.データベースシステムの概論を見ると、デカルト積がwhereが満たさなければ、生成されたメタグループ全体が表示されない.表示するにはjoin接続を使用する必要があります.
または左の接続を使用します.
接続がwhere句より効率的かどうかについては、諸説あるが、私も知らない.しかし、joinを使用するとwhereよりも論理的であることは間違いない.次は完全なコードです.
そして私はテストして、この論理はすべて間違っていて、countはすべてのsidに対して毎回の結果は同じです.これはsql文の実行順序に関係します.
問題はついに解決した.
CREATE TABLE status_db
(
sid int unsigned primary key AUTO_INCREMENT,
owner int unsigned not null,
photo_URL varchar(100) default '0',
audio_URL varchar(100) default '0',
video_URL varchar(100) default '0',
create_time varchar(20) not null ,
extra_message varchar(255),
display_time tinyint unsigned default 168,
latitude double not null,
longitude double not null,
geohash varchar(12) not null,
foreign key(owner) references user_static_db(uid) on delete cascade on update cascade
);
create table status_comment_message_db(
mid int unsigned not null AUTO_INCREMENT,
sid int unsigned not null,
uid int unsigned not null,
create_time varchar(50),
comment_content varchar(255),
refrence_mid int unsigned,
primary key (mid),
foreign key(sid) references status_db(sid) on delete cascade on update cascade
);
create table user_volatile_db(
uid int unsigned primary key,
school varchar(30),
user_name varchar(100),
signature varchar(255),
head_URL varchar(100),
video_URL varchar(100),
photo_URL varchar(100),
job varchar(255),
hobby varchar(255),
present varchar(1000),
foreign key(uid) references user_static_db(uid) on delete cascade on update cascade
);
クエリーstatus_dbのコンテンツの場合、ユーザの顔、名前、コメント数(コメントテーブルにsidがない場合は、このコメントを0と表す)を表示する必要があります.つまり、この場合は3つのテーブルを検索する必要があります.最初はこうしました
次は私が最初に書いたsql文です.
SELECT COUNT( mid ) AS comment_num, user_volatile_db.user_name, user_volatile_db.head_URL, status_db . *
FROM user_volatile_db, status_db, status_comment_message_db
WHERE user_volatile_db.uid
IN (
SELECT owner
FROM status_db
)
GROUP BY sid
ORDER BY sid DESC
LIMIT 0 , 10;
理想的にはcomment_numが0に等しい場合も表示すべきであるが、このような結果はすべての状態のコメント数が同じである.何が間違っているのかと思って、sql文を直して、簡略化してみました.
SELECT COUNT( mid ) AS comment_num, status_db . *
FROM status_db, status_comment_message_db
GROUP BY status_db.sid
ORDER BY sid DESC
LIMIT 0 , 10;
の結果、結果はやはりすべての状態のコメント数が同じであることがわかりました!突然自分が過ちを犯したことに気づいて、条件をつけなかった.SELECT COUNT( mid ) AS comment_num, status_db . *
FROM status_db, status_comment_message_db where status_comment_message_db.sid=status_db.sid
GROUP BY status_db.sid
ORDER BY sid DESC
LIMIT 0 , 10;
これでいいですが、コメント数が0のものは表示できません.これはなぜですか.データベースシステムの概論を見ると、デカルト積がwhereが満たさなければ、生成されたメタグループ全体が表示されない.表示するにはjoin接続を使用する必要があります.
select status_db.*,count(mid) as comment_num from status_comment_message_db right outer join status_db on status_comment_message_db.sid=status_db.sid group by status_comment_message_db.sid;
または左の接続を使用します.
select status_db.*,count(mid) as comment_num from status_db left outer join status_comment_message_db on status_comment_message_db.sid=status_db.sid group by status_comment_message_db.sid;
接続がwhere句より効率的かどうかについては、諸説あるが、私も知らない.しかし、joinを使用するとwhereよりも論理的であることは間違いない.次は完全なコードです.
SELECT status_db.*,user_volatile_db.user_name, user_volatile_db.head_URL,
count(mid) AS comment_num
FROM status_db
LEFT JOIN status_comment_message_db ON status_db.sid=status_comment_message_db.sid
LEFT JOIN user_volatile_db ON status_db.owner= user_volatile_db.uid
GROUP BY status_db.sid limit 0,10;
そして私はテストして、この論理はすべて間違っていて、countはすべてのsidに対して毎回の結果は同じです.これはsql文の実行順序に関係します.
SQL SELECT :
1、FROM ;
2、WHERE ;
3、GROUP BY ;
4、 ;
5、 HAVING ;
6、 ;
7、 ORDER BY
問題はついに解決した.