• 締切済み

SQLで重複値を除去したものを抽出したい

SQLで重複を除去したいのですが、DISTINCTやGROUP BYも検討したのですが、どうしても良い方法が見つからなかったので質問させて頂きます。 テーブルの構成は以下のようになっています。 roomsテーブル id(INTEGER) public(BOOLEAN) updated_at(DATETIME) created_at(DATETIME) messagesテーブル id(INTEGER) sendfrom_list_id(INTEGER) sendto_list_id(INTEGER) room_id(INTEGER)※roomsテーブルへの外部キー body(STRING) updated_at(DATETIME) created_at(DATETIME) 更に条件は以下のようになっています。 ・アウトプットとして得たいのは rooms.updated_at rooms.id rooms.public messages.room_id messages.sendfrom_list_id messages.sendto_list_id messagess.body の7カラム。 ・rooms.publicがTRUEである ・messages.room_id = rooms.idであること ・updated_atでDESCにソート このような条件を満たすSQL文は以下のように書くことができました。 SELECT R.updated_at, R.id, R.public, M.room_id, M.sendfrom_list_id, M.sendto_list_id, M.body FROM messages AS M, rooms AS R WHERE R.public = "t" AND M.room_id = R.id ORDER BY R.updated_at DESC; しかし、ここに更に「rooms.idが重複しないもののみ抽出」という条件を加えたいのですが、どうしてもうまく行きません。 DISTINCTでは複数の中から一部のカラムだけをDISTINCTすることはできないようですし、GROUP BYも考えましたがどうやれば良いかわかりませんでした。 どなたか良い方法を教えて下さい。

みんなの回答

  • Siegrune
  • ベストアンサー率35% (316/895)
回答No.2

「rooms.idが重複しないもののみ抽出」 ということなので、重複しているrooms.idのレコードは1件も出したくないのなら、 SELECT max(R.updated_at), R.id, max(R.public), max(M.room_id), max(M.sendfrom_list_id), max(M.sendto_list_id), max(M.body) FROM messages AS M, rooms AS R WHERE R.public = "t" AND M.room_id = R.id GROUP BY R.id HAVING count(*) < 2 ORDER BY R.updated_at DESC; ででると思うけど ・・・blobとかの型(つまりmax()を使えない型)の項目があればだめですが。⇒別のやり方有り。

  • todo36
  • ベストアンサー率58% (728/1234)
回答No.1

関連するQ&A

  • SQLで、アクセス集計について困っています。

    アクセス集計について困っています。 mysql> desc access_log; +------------+-------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +------------+-------------+------+-----+---------+----------------+ | id | bigint(20) | NO | PRI | NULL | auto_increment | | user_id | varchar(50) | YES | | NULL | | | ip | varchar(15) | YES | | NULL | | | created_at | datetime | NO | | NULL | | | updated_at | datetime | NO | | NULL | | +------------+-------------+------+-----+---------+----------------+ 5 rows in set (0.02 sec) mysql> select * from access_log; +----+---------+-----------+---------------------+---------------------+ | id | user_id | ip | created_at | updated_at | +----+---------+-----------+---------------------+---------------------+ | 1 | admin | 127.0.0.1 | 2010-11-13 21:56:54 | 2010-11-13 23:07:27 | | 2 | admin | 127.0.0.1 | 2010-11-13 21:56:54 | 2010-11-13 23:07:27 | | 3 | admin | 127.0.0.1 | 2010-11-14 21:56:54 | 2010-11-13 23:07:27 | | 4 | admin | 127.0.0.1 | 2010-11-14 21:56:54 | 2010-11-13 23:07:27 | | 5 | admin | 127.0.0.1 | 2010-11-15 21:56:54 | 2010-11-13 23:07:27 | +----+---------+-----------+---------------------+---------------------+ 5 rows in set (0.00 sec) 上記のように定義したテーブルがあります。 SELECT a.id, a.user_id, COUNT(*), DATE(a.created_at) AS date FROM access_log a WHERE (a.user_id = 'admin' AND a.created_at > '2010-11-01 00:00:00' AND a.created_at < '2010-11-29 23:59:59') GROUP BY date ORDER BY a.created_at; のようにして日別のアクセス数の集計をしています。 ここから、同じ日の同一IPのアクセスは1アクセスとして計算したいのですが、 どのようにSQLを書けばよいでしょうか? よろしくお願いいたします。

    • ベストアンサー
    • MySQL
  • mysqlのsql文について教えて下さい

    mysqlのsql文について教えて下さい 下記のようなテーブルとデータがあった場合に どうやれば 2,次郎だけを抽出できますか? 本日日付(2010-08-06)が 既にテーブルBにdateが存在する場合は 3,1,2010-08-04 3,1,2010-08-06を 対象外にしたいです。 Aテーブル id,user 1,太郎 2,次郎 3,3郎 Bテーブル targetid,homonid,date(datetime型) 3,1,2010-08-04 3,1,2010-08-06 3,2,2010-08-05 下記だと2010-08-04にヒットしてしまい(当たり前?)動作しません。 select distinct a.* from tblA a, tblB b where date_format(b.date, "%Y-%m-%d") <> "2010-08-06" ;

  • 指定された趣味を持つメンバーがいるグループを抽出するSQL

    グループテーブル、メンバーテーブル、趣味テーブルの3つのテーブルがあります。 あるメンバーはあるグループに属しており、趣味を1つ持っています。 以下がそのSQLです。 CREATE TABLE groups ( g_id int primary key ); CREATE TABLE members ( m_id int primary key , g_id int , h_id int ); CREATE TABLE hobbies ( h_id int primary key, h_name text ); INSERT INTO groups VALUES ( 1 ); INSERT INTO groups VALUES ( 2 ); INSERT INTO groups VALUES ( 3 ); INSERT INTO members VALUES ( 1, 1, 1); INSERT INTO members VALUES ( 2, 1, 3); INSERT INTO members VALUES ( 3, 1, 4); INSERT INTO members VALUES ( 4, 1, 4); INSERT INTO members VALUES ( 5, 2, 1); INSERT INTO members VALUES ( 6, 2, 2); INSERT INTO members VALUES ( 7, 2, 3); INSERT INTO members VALUES ( 8, 3, 2); INSERT INTO members VALUES ( 9, 3, 3); INSERT INTO members VALUES ( 10, 3, 4); INSERT INTO hobbies VALUES ( 1, 'sports' ); INSERT INTO hobbies VALUES ( 2, 'music' ); INSERT INTO hobbies VALUES ( 3, 'book' ); INSERT INTO hobbies VALUES ( 4, 'drive' ); 指定された趣味を持つメンバーがいるグループを抽出するにはどうすればいいでしょうか? 例えば、「読書が趣味なメンバーとドライブが趣味なメンバーがいるグループは?」「グループ1とグループ3」のような感じです。 一応自分で考えてみたのが、以下ですが、これだと趣味の指定が増減すると大きくSQLが変わってしまいます。 もっといいやり方はないでしょうか? 私はPostgreSQL8を使ってますが、汎用的なSQLであれば、そっちの方がいいです。 SELECT distinct m.g_id FROM members m join hobbies h ON m.h_id = h.h_id where h.h_name = 'drive' INTERSECT SELECT distinct m.g_id FROM members m join hobbies h ON m.h_id = h.h_id where h.h_name = 'book';

  • JOIN後同一名カラムから値がとれない

    こんにちは、mysqlでJOINした後、値を取得したいのですが、 2つのテーブルに値があり、片方を指定して取得する方法がわかりません。 いろいろ調べてみたのですがわかりませんでした。 どなたかご存知の方がいたら教えてください。 c_diary テーブルと c_member テーブルには、両方にr_datetimeという列があります。 それを別々の変数に代入したいのですが、うまくいきません。 SELECT * FROM c_diary left join c_member on c_diary.c_member_id = c_member.c_member_id $rs = mysql_query($sql); while ($item = mysql_fetch_array($rs)) { $c_diary_r_datetime = $item['c_diary.r_datetime']; $c_member_r_datetime = $item['c_member.r_datetime'] echo $c_diary_r_datetime."/".$c_member_r_datetime; } とやっているのですが、値が入らず空白となってしまいます。 どなたか、解決法をご存知の方がいたら教えてください。

    • ベストアンサー
    • MySQL
  • 一番新しいdatetime型列があるレコードを取得

    下記条件を満たすSQL文を知りたいのですが、どう書けばよいでしょうか? ■構成 Aテーブル ・「id」カラム ・「created_at」カラム … datetime型 ・「area」カラム Bテーブル ・「a_id」カラム ・「created_at」カラム … datetime型 ■前提 ・Aテーブルの1レコード(「id」カラム)に対して、0~複数のBテーブルレコード(「a_idカラム」)がある ・A.id = B.a_id ■欲しい内容 ・「Aテーブル」「Bテーブル」それぞれのカラム内容全部。※条件あり ▼条件1 Aテーブル「id」カラムに対応したBテーブルの「a_id」が複数ある場合には、該当Aテーブル内容+ Bテーブル「created_at」カラムの値が一番新しいレコードを返す(取得レコード数は常に1) ▼条件2 Aテーブル「id」カラムに対応したBテーブルの「a_id」がなかった場合には、該当Aテーブル内容+ Bテーブル側は何も返さない ▼条件3 ※同名カラムを取得する際には、カラム名先頭にそれぞれa、bを付与(「acreated_at」「bcreated_at」) ・後で、それぞれのテーブルカラムとして利用したいだけなので、それが出来れば形式にこだわりはありません

    • ベストアンサー
    • MySQL
  • MySQL 2つのテーブルから情報を得る

    【質問内容】 出稿した求人広告に関する情報を収めたデータベース内に、以下の2つのテーブルがあります ※以下の文章を読むより、添付画像をご覧頂いたほうが分かりやすいと思いますが 1.出稿した求人広告の情報 テーブル名:ad_info id ID plan 広告プラン名 date_from DATE 広告開始日 2011-12-16 date_until DATE 広告終了日 2011-12-31 price 広告料金 2.求人サイトへのアクセス情報(広告掲載期間のみ毎日2時間おきに収集) テーブル名:daily_access id ID created_at DATETIME クローリングした日時 2011-12-16 17:00:00 pv プレビュー数 applicants 応募者数 occupation_ranking 職種別画面での自社の掲載順位 newly_ranking 新着企業画面での掲載順位 この2つのテーブルからad_infoの広告ごとに(その掲載期間ごとに)、daily_accessのデータを集計したいと思っています。しかしそのためのSQL文がうまく書けず、詰まっています。 どうか良い方法を教えていただけませんでしょうか。 あるいは「テーブル構造自体を変えたほうがいいよ」、「SQL文の書き方が良くないよ」など直接関係のないことでも大歓迎です。 よろしくお願いします。 【MySQLバージョン情報】 $ mysql --version mysql Ver 14.14 Distrib 5.5.16, for Linux (x86_64) using EditLine wrapper 【テーブル作成文】 CREATE TABLE `ad_info` ( `id` INTEGER NOT NULL AUTO_INCREMENT, `plan` VARCHAR(30) DEFAULT NULL, `date_from` DATE DEFAULT NULL, `date_until` DATE DEFAULT NULL, `price` INTEGER DEFAULT NULL, PRIMARY KEY (id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; CREATE TABLE `daily_access` ( `id` INTEGER NOT NULL AUTO_INCREMENT, `created_at` DATETIME NOT NULL, `pv` INTEGER DEFAULT NULL, `applicants` INTEGER DEFAULT NULL, `occupation_ranking` INTEGER DEFAULT NULL, `newly_ranking` INTEGER DEFAULT NULL, PRIMARY KEY (id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

    • ベストアンサー
    • MySQL
  • select文について

    現在、"user"というテーブルに"id"と"date(datetime)"という項目があり、その"date"にあるデータの中から月を指定して抽出したくて以下ようなSQL文を書いたのですがうまくいきません。 SELECT `id` FROM `user` WHERE convert((SELECT extract(month from `date`) FROM `user`), INTEGER) = 9 mysql5.0です。 よろしくお願いします。

    • ベストアンサー
    • MySQL
  • SQLのSELECT文について

    以下の注文テーブルで、注文件数と送料と注文合計金額を一度に取得する場合、以下のようなSQL文で合っていますか? "SELECT order.total, order.delivery_fee, SUM(order.total * order.tax) AS total_for_paying FROM order"; CREATE TABLE `order` ( `id` bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT, `status` tinyint(3) UNSIGNED NOT NULL DEFAULT '0', `order_payment_status` tinyint(3) UNSIGNED NOT NULL DEFAULT '0', `buyer_id` bigint(20) UNSIGNED NOT NULL, `discount` INT(11) UNSIGNED NOT NULL, `delivery_fee` INT(11) UNSIGNED NOT NULL, `charge` INT(11) UNSIGNED NOT NULL, `total` INT(11) UNSIGNED NOT NULL, `tax` INT(11) UNSIGNED NOT NULL, `total_with_tax` INT(11) UNSIGNED NOT NULL, `total_for_paying` INT(11) UNSIGNED NOT NULL, `use_point` INT(11) UNSIGNED NOT NULL, `created` DATETIME NOT NULL, `updated` DATETIME NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4;

    • ベストアンサー
    • MySQL
  • sqlスクリプトエラーその2について

    以下のコマンドを実行するとtrueのところでエラーになります。 以前実行したときはうまくいったのですが原因がよくわかりません。 C:\>mysql\bin\mysqladmin -u root -p CREATE sample2 Enter password: **** C:\>mysql\bin\mysql -u root -p sample2 < c:\database.sql Enter password: **** ERROR 1054 at line 22: Unknown column 'true' in 'field list' <database.sql>-- ユーザを表すテーブル create table schedule_user ( id integer primary key, -- ユーザID name text not null, -- 名前 mailaddress text not null, -- メールアドレス password text not null); -- パスワード -- 予定を表すテーブル create table schedule ( id integer primary key, -- 予定ID user_id integer not null, -- この予定を入れたユーザのユーザID subject text not null, -- 予定の題名 content text not null, -- 予定の内容 start_time timestamp not null, -- 予定の開始日時 end_time timestamp not null, -- 予定の終了日時 place text, -- 予定の場所 comment text, -- 予定のコメント is_publish bool not null); -- 予定の公開/非公開フラグ -- テスト用のデータ insert into schedule_user values(1, 'itboost','motomatu@itboost.co.jp', 'itboost'); insert into schedule values(1, 1, '予定1', '予定1です', '2003-01-01 10:00', '2003-01-01 10:30', 'A社', '予定1のコメントです。', true); insert into schedule values(2, 1, '予定2', '予定2です', '2003-01-01 10:00', '2003-01-02 10:30', 'B社', '予定2のコメントです。', false); insert into schedule values(3, 1, '予定3', '予定3です', '2003-01-01 20:00', '2003-01-03 22:30', 'C社', '予定3のコメントです。', true); ご教授よろしくおねがいします。

  • テーブル作成 外部参照 配列

    はじめまして maruchanといいます。 外部参照のところで詰まっています。 例: テーブルA id primary key name text と言うテーブルがあるとして CREATE TABLE B ( id PRIMARY KEY, z_id integer[] constraint constname references A(id) ); ということを実行したいんですが エラーが出ます。 ERROR: syntax error at or near "cast" at character 98 なにか気づく点がありましたら 返事ください。 宜しくお願いします。