前回から続きます
distinct ですが、MySQL(3.23.58)だと、並び替えをしないと判明。
(試してみました。『出てきた順』のようです。内部的にソートせずにマージしているのでしょうか?)
PostgreSQL(7.3.4)はdistinctした列でソート(並び替え)が行われます。(だから今回の不具合が出ました。)
ちなみにOracleもPostgreSQLと同じです。
今回の問題、
mt_commentと、mt_entryの結合にあると思うのです。
ER図にしてみました。

まず、最近のコメントを持っているエントリーを検索しなければなりません。
最近のコメントを取るためには、MT_COMMENTの中の、COMMENT_CREATED_ONで判断します。
エントリ(MT_ENTRY)と、コメント(MT_COMMENT)は、ENTRY_IDとCOMMENT_ENTRY_IDで結合されます。
エントリと結合するコメントのうち、いちばん最新のものを持ってきて、それをCOMMENT_CREATE_ONの降順でOrderするんです。
それで↓のようなクエリをかけたらいいのでは?っと思っていたのです。
select
entry_id
,entry_title
,comment_author
,to_char(comment_created_on,'yyyy/mm/dd')
from mt_entry
,mt_comment cm1
where entry_id = comment_entry_id
and comment_created_on =
(
select max(comment_created_on)
from mt_comment cm2
where cm2.comment_entry_id = cm1.comment_entry_id
)
order by comment_created_on desc
limit 5
(結果)
id | entry_title | author | comment_create
----+---------------------------------+--------+----------------
36 | PostgreSQLへ...その4?? | (o) | 2004/08/13
35 | PostgreSQLへ....その3 | megu | 2004/08/13
26 | なぜ、Web上で日記を書くのか?? | megu | 2004/08/10
23 | 管理画面のアクセス制限 | megu | 2004/08/10
25 | Audi newA6見てきました | megu | 2004/08/04
(5 rows)
相関副問い合わせを使っています。
副問い合わせ内では親問い合わせで取得したエントリIDのデータ中
いちばんcomment_created_onの値が大きいものを取り出します。
#しかしながら、私の力ではこれをどーやってMTに載せればよいのかわかりません。
#こういった問い合わせは無理があるのかも。
それで、教えていただいた、mizさんのパッチですが、
ありがたく更新させていただきました...m(_ _)m。
↓はmizさんのパッチをあてさせていただいた後のSQLです。
select entry_id,
entry_blog_id,
entry_status,
entry_author_id,
entry_allow_comments,
entry_title,
entry_excerpt,
entry_text,
entry_text_more,
entry_convert_breaks,
entry_to_ping_urls,
entry_pinged_urls,
entry_allow_pings,
entry_keywords,
entry_tangent_cache,
entry_basename,
entry_category_id,
entry_created_on,
entry_created_by,
entry_modified_on,
entry_modified_by
from
(
select
entry_id,
entry_blog_id,
entry_status,
entry_author_id,
entry_allow_comments,
entry_title,
entry_excerpt,
entry_text,
entry_text_more,
entry_convert_breaks,
entry_to_ping_urls,
entry_pinged_urls,
entry_allow_pings,
entry_keywords,
entry_tangent_cache,
entry_basename,
entry_category_id,
entry_created_on,
entry_created_by,
entry_modified_on,
entry_modified_by,
max (comment_created_on)
as entry_comment_created_on
from
mt_entry,
mt_comment
where (comment_blog_id = ?)
and (comment_visible = ?)
and entry_id = comment_entry_id
and (entry_blog_id = ?)
and (entry_status = ?)
group by entry_id,
entry_blog_id,
entry_status,
entry_author_id,
entry_allow_comments,
entry_title,
entry_excerpt,
entry_text,
entry_text_more,
entry_convert_breaks,
entry_to_ping_urls,
entry_pinged_urls,
entry_allow_pings,
entry_keywords,
entry_tangent_cache,
entry_basename,
entry_category_id,
entry_created_on,
entry_created_by,
entry_modified_on,
entry_modified_by) t
order by entry_comment_created_on desc
limit 5
相関副問い合わせのかわりに、
From句の中にさらにSELECT命令、
その中でグルーピングして、各々のエントリーの中でcomment_created_onのいちばん大きいものを取り出しています。
コメント日付のいちばん新しい行を取ってくるViewを作成したのと同様だと思います。
(この場合、検索条件が内側のSELECT(=view)に含まれているので懸念される検索速度の低下には繋がらないと思いますが、メインカーソルで条件を絞り込んだ上で、その結果に対して副問い合わせを行ったほうがよい場合もあります。)
きっと、MTに実装するには、これがいちばん良い方法なんだと思います。
ソースと照らし合わせみると
「ほぅ~、こうやって書くのね」
と、思うのですが
じゃっ、いざ自分が考えていたクエリを実行させるにはどうすればいい?
#ちょっと時間をかけて考えたいとは思うけれど。
なんだかとってもわかりずらいソースプログラム。
もともと、MTのテーブルはフクザツな関係は持っていないと思うのです。
唯一、ちょっと難しい検索を使っているのがこの部分(最近のコメント)だったのではないでしょうか?
ではなぜMySQLではSQLの組み立て部分が異なってくるのか?
できれば同じ問い合わせを使うほうがいいに決まっているのに....なぁんて思ってしまうのですが...。
バージョンによるのかもしれませんが、私のMySQL(3.23.58)では、相関副問い合わせをかけようとすると、エラーとなります。From句にSELECT命令を書いても駄目です。
副問い合わせも駄目でした。
5.0のマニュアルでは出来るようなこと書いてあるのですが...
おそらく、普及しているであろうバージョンのMySQLにあわせると、副問い合わせを使うわけにはいかないのでしょう。
あまり悩んでいても本来の目的からかなり脱線してしまっているので、
このくらいにしておいたほうがいいのかも??
投稿者 megu : 2004年08月15日 15:58
