SQL条件抽出のアドバイスをお願いします

このQ&Aのポイント
  • user_accountテーブルとlogテーブルの結合についてアドバイスをお願いします。
  • logテーブルの中から最新の発言内容を取得する方法について教えてください。
  • 期待する結果のサンプル出力を示しました。どのようなSQL文を使えばこの結果が得られますか?
回答を見る
  • ベストアンサー

SQLの条件抽出について

ちょっと躓いてしまったのでアドバイスが頂けたらと思います。 user_accountというテーブルと、logというテーブルがあります。 logというテーブルには各ユーザーの書き込み履歴が残されており、日付がtimestamp形式で格納されています。 ユーザー一覧に最終発言内容をくっ付けて表示したいのですがうまくいきません。 SELECT DISTINCT * FROM user_accounts LEFT JOIN (SELECT * FROM log ORDER BY update_date DESC ) aaa ON user_accounts.pkey = aaa.user_accounts_pkey; などと記述してみましたが、思うような結果になりません。 自分の理想とする結果は以下のような出力結果です。 +----+----+----+--+-----------------+----------------+-----------+ | pkey| user| pass|      comment| update_date| +----+----+----+--+-----------------+----------------+-----------+ |  1 | test1| pass01|test03 written by test1| 40813| |  2 | test2| pass02|testestest        | 40690| どうか、お知恵を貸してください。

質問者が選んだベストアンサー

  • ベストアンサー
  • nora1962
  • ベストアンサー率60% (431/717)
回答No.1

WINDOW関数が使えるなら select pkey, user, pass, comment, update_date from ( SELECT user_accounts.*, log.comment, log.update_date, row_number() over(partition by user_account.pkey order by log.update_date ) rn FROM user_accounts LEFT JOIN log ON user_accounts.user = log.user_accounts_pkey) T where rn = 1; そうでなければ SELECT user_accounts.*, log.comment, log.update_date FROM user_accounts LEFT JOIN ( select * from log where not exists ( select 1 from log l2 where log.user_accounts_pkey=l2.user_accounts_pkey and log.update_date<l2.update_date ) ) l ON user_accounts.pkey = l.user_accounts_pkey

t_netbug
質問者

お礼

いち早く反応してくださり、ありがとうございます。 not existsにこのような使い方があるとは。。。 もっと精進します。ありがとうございます。

その他の回答 (2)

回答No.3

訂正します。 まずは素直に最終発言を抽出します。 select user_account_pkey,max(update_data) from log group by user_account_pkey これを使って log から必要なレコードをのみを抽出、user_account テーブルと結合して結果を得ます。 select ua.pkey,ua.user,ua.pass,l.comment,l.update_date from log l,user_account ua where l.user_account_pley = ua.pkey and (l.user_account_pkey,update_data) in ( select user_account_pkey,max(update_data) from log group by user_account_pkey ) ※SQLは机上で書きました動作確認はしていません。

t_netbug
質問者

お礼

ありがとうございます、group byの使い方が分からず、四苦八苦していた所にumekihajime様の書き込みがあり、大変参考になりました。 自分が求めていた書き方に一番近い書き方をされていたものの、動作確認をしていないとの事もあり、umekihajime様には大変恐縮ではありますが、最初に書き込みを下さった方をベストアンサーとさせていただきました。 ありがとうございました。

回答No.2

まずは素直に最優発言を抽出します。 select user_account_pkey,max(update_data) from log group by user_account_pkey これを使って log から必要なレコードをのみを抽出、user_account テーブルと結合して結果を得ます。 select ua.pkey,ua.user,ua.pass,l.comment,l.update_date from log l,user_account ua where l.user_account_pley = ua.pkey and (l.user_account_pkey,update_data) in ( select user_account_pkey,max(update_data) from log group by user_account_pkey ) ※SQLは机上で書きました動作確認はしていません。

関連するQ&A

  • SQL文作成のお願い

    前提として下記のようなテーブルがあります。 テーブル名:test フィールド: 1)id: varchar, not null 2)name: varchar 3)date: timestamp with time zone, not null このテーブルに下記のようなレコードがあります。 '00001', 'A', '2005-01-01 00:00:00' '00001', 'B', '2005-07-01 00:00:00' '00001', 'C', '2005-11-01 00:00:00' '00002', 'X', '2005-01-20 00:00:00' '00002', 'Y', '2005-07-20 00:00:00' '00002', 'Z', '2005-11-20 00:00:00' ■今やりたいこと このテーブルからidごとにdateフィールド値が最近のレコードを取得したい。 ■やってみたこと 下記SQLを発行しました。 >select id, max(date) from test group by id order by id 結果==> 00001 2005-11-01 00:00:00 00002 2005-11-20 00:00:00 実際はnameフィールドの値も取得したいのですが、group by句を使うとフィールド指定ができませんでした。 ■だめだったSQL select id, name, max(date) from test group by id order by id どのようにSQLを書けばよろしいでしょうか?

  • SQL文で作ったデータを使ったUPDATE

    環境はMySQL5.6です。 下記のテーブルccがあります。 【cc】 shisan  user 500  tanaka 1000  mikami 400   tanaka 1300  mikami SELECT Total, user FROM (SELECT SUM( cc.shisan ) AS Total, user FROM cc GROUP BY user) AS t1 とすることによりSQL上にt1テーブルを作ることが出来ます。 【t1】 Total  user 900  tanaka 2300  mikami 次に、このt1テーブルのTotalの数値を下記のmoney_tableにあるcash欄に挿入(UPDATE)したいと考えています。 【money_table】 cash  user 0   tanaka 0   mikami そこで下記のSQL文を作ったのですがエラーになります。 UPDATE money_table,cc SET money_table.cash=t1.Total FROM (SELECT Total, user FROM (SELECT SUM( cc.shisan ) AS Total, user FROM cc GROUP BY user) AS t1) WHERE money_table.user=t1.user どこがいけないのかご指導いただけませんでしょうか? よろしくお願いいたします。

    • ベストアンサー
    • MySQL
  • SQLのこと:distinctして並び替えたい

    select * from (select distinct on (aaa) * from bbb) as ccc order by ddd テーブルbbbのaaaというフィールドが重複せず、しかも他のフィールドで並び替えをしたかったら、このような書き方以外ありますか?データベースはPostgreSQLです。 この書き方で不都合が出ているというわけではありませんが、どう書けば、パフォーマンス的にも良いSQLになるか、詳しい方がいらっしゃいましたら、お願いします。

  • SQL 複数のテーブルから重複なしでデータを取得

    同じフィールド名[名前]を持つテーブルが複数個あります。 仮にテーブル名を、A、B、C、Dの4個だとします。 それらのテーブルから、フィールド名[名前]のデータを重複なしで取得したいのですが、SQL文が思いつきません。 取得するフィールドは[名前]だけです。 select distinct(名前) from A union select distinct(名前) from B union select distinct(名前) from C union select distinct(名前) from D だと、各表に同じ名前が存在する場合は結果も重複してしまい、期待する結果が得られませんでした。 環境はOracle 9iです。 SQL文を教えてください。よろしくお願いします。

  • グループ中で最大値を含む行を抽出するSQLはどう書けば良いでしょうか

    列A,Bでグループ化し、グループ中で列Cが最大値の列を取得したいのです。 数百万件あるので極力低コストにしたく、 副問合せはINDEXが効かないと聞いたのですが、 それ以外思いつきませんでした。 副問合せしない方法はないでしょうか? また、副問合せの中でコストの低いSQLはどんなものでしょうか。 ■テーブルです 名前 型 CUST_ID CHAR(8) BRANCH_ID CHAR(4) VALID_DATE DATE MYDATA VARCHAR2(20) CUST_ID BRAN VALID_DA MYDATA 19740704 0000 06-01-01 comment0001 19740704 0000 05-12-01 comment0000 19740704 0000 06-02-01 comment0002 19740704 0001 06-01-01 comment0011 19740704 0001 06-03-01 comment0012 ■このような結果が欲しいのですが。。。 CUST_ID BRAN VALID_DA MYDATA 19740704 0000 06-02-01 comment0002 19740704 0001 06-03-01 comment0012 ■考えたSQLです(検証済) select a.cust_id,a.branch_id,a.valid_date,a.mydata from test a,(select cust_id,branch_id,max(valid_date) as mvd from test group by cust_id,branch_id) b where a.cust_id=b.cust_id and a.branch_id=b.branch_id and a.valid_date=b.mvd ; select a.cust_id,a.branch_id,a.valid_date,a.mydata from test a where not exists (select * from test b where a.cust_id=b.cust_id and a.branch_id < b.branch_id) ; select cust_id,branch_id,valid_date,mydata from test where (cust_id,branch_id,valid_date) in (select cust_id,branch_id,max(valid_date) from test group by cust_id,branch_id) ; select cust_id,branch_id,valid_date,mydata from (select cust_id,branch_id,valid_date,mydata,max(valid_date) over(partition by cust_id,branch_id) as mvd from test) where valid_date=mvd ;

  • SQL文「DISTINCT」の「ORDER BY」について

    SQL文「DISTINCT」の「ORDER BY」について教えて下さい。 A列をDISTINCTで重複行の排除をしています。 その後、B列でORDER BYをかけたいのですが、エラーが 出てしまいます。A列でのORDER BYは成功します。 何か良い方法があれば教えて下さい。 よろしくお願いします。 SQL="SELECT DISTINCT A列 from table " &_ "WHERE (table.C列='100') " &_ "ORDER BY (table.B列) ASC " ⇒エラー    "ORDER BY (table.A列) ASC " ⇒成功

  • SQL文 この部分はなんていうのでしょう?

    SELECT T_テーブル1.フィールド1 FROM T_テーブル1 ORDER BY T_テーブル1.フィールド1; なら、 ”ORDER BY句” SELECT T_テーブル1.フィールド1 FROM T_テーブル1 WHERE (((T_テーブル1.フィールド1)="A")); なら ”WHERE句” と言いますが、 DELETE Table1.* FROM Table1; や UPDATE テーブル1 Set テーブル1.フィールド1 = "い" WHERE (((テーブル1.フィールド1)=”あ")); や DROP Table Table1; の deleteやupdateやdropの部分は何て言うのでしょうか? そのまま、SELECT句DELETE句などというのでしょうか?

  • <SQL>条件付きで最小値レコードを抽出する方法

    SQLite3.7.5を使っています。 以下<抽出前>の様なテーブルから、col2の値が"FALSE"で(col1=3,4,5の3つ)かつ、col3が最小値(col3=3)であるレコードを<抽出後>のように抽出するSQL文をご教示ください。 <抽出前> col1 | col2 | col3 1 | true | 3 2 | true | 0 3 |false | 3 4 |false | 5 5 |false | 3 <抽出後> col1 | col2 | col3 3 |false | 3 5 |false | 3 自分で考えたSQL文は以下です。 抽出結果は問題ないのですが、同じSELECT文を2回書いていてだいぶ効率悪いことをしているのではないかと思い質問しました。 よろしくお願い致します。 SELECT * FROM (SELECT * FROM test WHERE (col2 = false)) WHERE col3 = (SELECT min(col3) FROM (SELECT * FROM test WHERE (col2 = false)))

  • 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" ;

  • ACCESS SQLのINSERTについて

    TBLというテーブルにINSERT文を使用して1行レコードを追加したいです。TBLテーブルのカラムAにはシステム日付を、カラムBには別テーブルのselect count(*)の実行結果を挿入したいのですがうまくいきません。何か良い方法はございませんでしょうか? INSERT INTO カウンタ統計 ( [DATE], USER_COUNT ) VALUES (date(), (SELECT COUNT(*) FROM hiplus_HW_USER)); ※日付は問題なく挿入できるのですがSELECT文の結果が挿入できない状況です。宜しくお願いします.