PostgreSQLについての質問です。以下のようなテーブルを考えます。

id | user_id | date
---|---------|---------
 1|  1| 2007/3/4
 2|  2| 2007/5/4
 3|  1| 2007/3/6
 4|  3| 2007/7/4
 5|  2| 2007/4/4
 6|  3| 2007/3/4
ORDERとLIMITを使わずに「各user_id」の「今日の日付より過去」かつ「今日に近いもの」の「id」を取得するSQLを教えてください。もしくは「できない」ということを納得できる形で説明してください。
以上、よろしくお願いします。

回答の条件
  • 1人2回まで
  • 登録:
  • 終了:2007/07/04 20:59:09
※ 有料アンケート・ポイント付き質問機能は2023年2月28日に終了しました。

ベストアンサー

id:taknt No.1

回答回数13539ベストアンサー獲得回数1198

ポイント100pt

未確認ですが こんな感じでできると思います。

select ta.id from テーブル ta,(SELECT テーブル.user_id u, Max(テー

ブル.date) d

FROM テーブル2

WHERE (((テーブル.date)<now))</p>

GROUP BY テーブル.user_id ) tb where ta.user_id = tb.u and ta.date = tb.d

id:k1LoW

今確かめたところ無事目的の結果を得ることができました!

ありがとうございます!

一部修正した部分は、now()の部分をdate_truncをかませて時刻でなく日付で判断する形にしただけです。

2007/07/04 20:55:52

その他の回答1件)

id:taknt No.1

回答回数13539ベストアンサー獲得回数1198ここでベストアンサー

ポイント100pt

未確認ですが こんな感じでできると思います。

select ta.id from テーブル ta,(SELECT テーブル.user_id u, Max(テー

ブル.date) d

FROM テーブル2

WHERE (((テーブル.date)<now))</p>

GROUP BY テーブル.user_id ) tb where ta.user_id = tb.u and ta.date = tb.d

id:k1LoW

今確かめたところ無事目的の結果を得ることができました!

ありがとうございます!

一部修正した部分は、now()の部分をdate_truncをかませて時刻でなく日付で判断する形にしただけです。

2007/07/04 20:55:52
id:kn1967 No.2

回答回数2915ベストアンサー獲得回数301

ポイント35pt

SELECT id,usrt_id,date,(SELECT MAX(date) FROM t WHERE usrt_id = a.usrt_id AND date < a.date GROUP BY usrt_id)

FROM t a;

id:k1LoW

詳しい検証はまだですが、一部修正した形で(usert_id→user_id)ためしたところ、出力結果が6レコードでてきてしまいます。

上記の点は解消できるとして、サブクエリの部分には目的の結果の逆の値が出力されていました。

実際に使ったSQL文を付記します。

SELECT id,user_id,date,(SELECT MAX(date) FROM test_table WHERE user_id = a.user_id AND date < a.date GROUP BY user_id)

FROM test_table a;

-------

追記です。正しくは「逆の値」ではなく「ほぼ逆の値」でした。

2007/07/04 20:57:42
  • id:taknt
    </p>

    は ゴミです。
  • id:taknt
    あ あと テーブル名は テーブルだけで テーブル2は テーブルの間違いです。

    テーブル名も 書いてあると よかったですけどね。
  • id:k1LoW
    どうもありがとうございます。確かにテーブル名を書いておくのを忘れていました。とりあえず、検証ではtest_tableという名前を使ったこと付記しておきます。
  • id:k1LoW
    takntさんの回答から実際に使ったSQL文を付記しておきます。
    SELECT ta.id from test_table ta,(SELECT test_table.user_id AS u, Max(test_table.date) AS d
    FROM test_table
    WHERE (((date_trunc('day',test_table.date))<date_trunc('day',now())))
    GROUP BY test_table.user_id ) tb where ta.user_id = tb.u and ta.date = tb.d;

    なぜかASを使わないとシンタックスエラーになる部分がありましたが、今回の出力結果とは関係のない部分だと思っております。
  • id:taknt
    あ そういや 今日の日付を取得するのを PostgreSQL用に 直してませんでした。

    ACCESSで SQLを確認しました。
  • id:k1LoW
    takntさんの回答で目的とする出力結果を得ることができましたので質問を閉めたいと思います。
    これからSQL文を検証したいと思います。
    みなさんどうもありがとうございました。
  • id:kn1967
    「今日」というキーワードがdataフィールドに記されている日付の事ではなく「操作時点の日付」だったのですね。
    理解力不足で申し訳ないです。

    検証している間に解決されたようですので蛇足になりますが足跡だけしるさせていただきます。

    ■データ準備
    create table test_table (id INT4,user_id INT4,date DATE)
    INSERT INTO test_table(id,user_id,date)VALUES(1,1,'2007-3-4');
    INSERT INTO test_table(id,user_id,date)VALUES(2,2,'2007-5-4');
    INSERT INTO test_table(id,user_id,date)VALUES(3,1,'2007-3-6');
    INSERT INTO test_table(id,user_id,date)VALUES(4,3,'2007-7-4');
    INSERT INTO test_table(id,user_id,date)VALUES(5,2,'2007-4-4');
    INSERT INTO test_table(id,user_id,date)VALUES(6,3,'2007-3-4');
    ■動作テスト1
    SELECT id,user_id,date,(SELECT MAX(date) FROM test_table WHERE user_id = a.user_id AND date < a.date GROUP BY user_id)
    FROM test_table a;
    ■結果1
    id | user_id | date | ?column?
    ---|---------|----------|-----------
     1|   1| 2007-3-4 |
     2|   2| 2007-5-4 | 2007-04-04
     3|   1| 2007-3-6 | 2007-03-04
     4|   3| 2007-7-4 | 2007-03-04
     5|   2| 2007-4-4 |
     6|   3| 2007-3-4 |

    ■動作テスト2
    SELECT id,user_id,date,(SELECT MAX(date) FROM test_table WHERE user_id = a.user_id AND date < a.date GROUP BY user_id)
    FROM test_table a
    WHERE NOT EXISTS(SELECT date FROM test_table WHERE user_id = a.user_id AND date > a.date);
    ■結果2
    id | user_id | date | ?column?
    ---|---------|----------|-----------
     2|   2| 2007-5-4 | 2007-04-04
     3|   1| 2007-3-6 | 2007-03-04
     4|   3| 2007-7-4 | 2007-03-04

    ・・・・以上、蛇足でした。
  • id:kn1967
    ■動作テスト3
    SELECT id,user_id,date
    FROM test_table a
    WHERE NOT EXISTS(SELECT date FROM test_table WHERE user_id = a.user_id AND date > a.date);
    ■結果3
    id | user_id | date
    ---|---------|----------
     2|   2| 2007-5-4
     3|   1| 2007-3-6
     4|   3| 2007-7-4
    蛇足の蛇足ですが・・・
  • id:kn1967
    さらに蛇足・・・
    Access→Date
    PostgreSQL→CURRENT_DATE
    これが肝心だったりする。寝起きで書き忘れに気付いた私って・・・

この質問への反応(ブックマークコメント)

「あの人に答えてほしい」「この質問はあの人が答えられそう」というときに、回答リクエストを送ってみてましょう。

これ以上回答リクエストを送信することはできません。制限について

回答リクエストを送信したユーザーはいません