SQLノート、select countが0の疑惑について解決します

4026 ワード

SQLテーブルは次の2つあります.
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

問題はついに解決した.