• ベストアンサー

SQL一発でカレンダー表示は可能ですか?

お世話になっております。 とあるログテーブルからデータを抽出する際、 日付でグルーピングをかけて集計した上、 カレンダーのような抽出結果にする必要があり、悩んでいます。 悩みどころは ・『データがない日付の場合も表示する』 ・『SQL1本で出さなくてはならない』 です。 【サンプル】ログテーブル -------------------- ログ日時 | 回数 | -------------------- 2006/07/01|  2 | 2006/07/03|  1 | 2006/07/05|  8 | -------------------- 上記テーブルから ログ日時が2006/07/01から2006/07/05までのデータを取得した場合、 結果をこういう形で抽出したいのです。 -------------------- ログ日時 | 回数 | -------------------- 2006/07/01|  2 | 2006/07/02|    |→ログテーブルにデータ無し 2006/07/03|  1 | 2006/07/04|    |→ログテーブルにデータ無し 2006/07/05|  8 | -------------------- データベースはsybase IQです。 なにか良い方法をご存知の方がいらっしゃいましたら ご教示いただけませんか???

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

  • ベストアンサー
回答No.3

Sybase IQでは、OUTER JOINはサポートされているのですよね? 事前準備として、カレンダー(7月なら、7月1日~31日)を管理するテーブルを作っておいて、ログの日付の情報とLEFT JOINさせた上でGROUP BYすれば、簡単な検索SQLで実現できます。 以下の例では、カレンダーを管理するテーブルには日付しか入れていませんが、休日を管理したり用途はいろいろあると思います。 1.表定義&データ例 create table user_calendar (user_date date); insert into user_calendar values('2006-7-1'); insert into user_calendar values('2006-7-2'); insert into user_calendar values('2006-7-3'); ~中略~ insert into user_calendar values('2006-7-31'); 2.ログ情報・・・既存のテーブル create table log_table (log_date date, log_data varchar(100)); insert into log_table(log_date) values('2006-7-1'); insert into log_table(log_date) values('2006-7-3'); insert into log_table(log_date) values('2006-7-3'); insert into log_table(log_date) values('2006-7-3'); insert into log_table(log_date) values('2006-7-5'); insert into log_table(log_date) values('2006-7-5'); insert into log_table(log_date) values('2006-7-5'); insert into log_table(log_date) values('2006-7-5'); insert into log_table(log_date) values('2006-7-5'); 3.検索SQL例 select user_date,count(log_date) from user_calendar left join log_table on user_date=log_date group by user_date order by user_date;

dpdyna
質問者

お礼

有難う御座います。 この方法で実装したところうまく行きました! しかしその後、 クライアントから仕様変更の連絡があり、 データがある日だけ出せばOKということになりました。 それでも私の今後の開発にとても役立つお話でした。 有難う御座いました!

dpdyna
質問者

補足

OUTER JOIN(LEFT,RIGHT,FULL)は全てサポートしているようです。

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (3)

  • CHRONOS_0
  • ベストアンサー率54% (457/838)
回答No.4

sybase IQにどのような関数があるのか知りませんので考え方だけ レコードを作製するには種がいります というこごで数字だけのテーブルを用意します num ---- 0 1 ・ ・ 99 <-必要十分な大きさ+余裕まで このテーブルからクエリを作り ログ日時最小+num日という式フィールドを作り 抽出条件に<=ログ日時最大 とすればログ期間の抜けのないカレンダーが得られます

dpdyna
質問者

お礼

有難うございます。 なるほど、思いつきもしなかった! カレンダーテーブルそのものでなくても 軸となるものがあればイケますね!

全文を見る
すると、全ての回答が全文表示されます。
  • galluda
  • ベストアンサー率35% (440/1242)
回答No.2

がると申します。 ちぃと補足になるのですが。 表示部分(俗にviewって呼ばれる場所ですね)で、直接DBのデータをfetchしてるわけではないんですよね?(もし直接やってるんだと…ちぃとインタフェースいじくったほうがよいように思われます) 基本的には「表示部分に渡すデータ」を細工になるので、Dbのfetch部分とデータを渡す部分の間に「欠落してる日付のデータを突っ込む」処理をaddするとよろしいのではないかと愚考いたします。 以上、何かの参考にでもなれば幸いです。

dpdyna
質問者

お礼

有難うございます。 >>「欠落してる日付のデータを突っ込む」処理をaddする インターフェース的にコレが難しいらしいのです。

全文を見る
すると、全ての回答が全文表示されます。
  • galluda
  • ベストアンサー率35% (440/1242)
回答No.1

がると申します。 んっと…基本的に「ないデータを抽出する」ってのは、DBの基本的意義に反する要求だと思うのですが。 無論「表示部分で出したい」という要求は割合によくありえる話ではあるのですが、 ・SQLでそれを処理する 必要はあるのでしょうか? 素直に「SQLでデータを抽出、プログラムでデータを処理」ではなにかまずいでしょうか?

dpdyna
質問者

お礼

回答ありがとうございます。 表示側のアプリケーションの問題で厳しいらしいのです。 やはり基本『無理』ですよね・・・。 説得して表示部分で何とかしてもらうようにします。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • SQLでグルーピングしてやや複雑な集計する方法

    SQLでグルーピングしてやや複雑な集計する方法 こういうことってやりたい時あるよなーと思いつつ いい方法が思い浮かばないので質問させてください。 日付ごとにタイプなどの条件により集計して、 1行で1日分のデータを並べて出力したいと思っています。 とりあえずイメージを提示します。 テーブルイメージ -------------------------- 日付     額 タイプ 20090101  5000  1 20090101  1000  1 20090101  3000  2 20090101  2000  2 20090101  -200  4 20090101  3000  4 20090101  2000  4 20090102  1000  1 20090102  1000  2 20090102  1000  2 20090102  -100  4 20090102  4000  4 20090102  3000  4 -------------------------- 出力イメージ ----------------------------------------------------- 日付   タイプ1 タイプ2 タイプ4(正) タイプ4(負) 20090101   6000   5000   5000   -200 20090102   2000   2000   7000   -100 ----------------------------------------------------- 複問い合わせを駆使すればできるような気もするのですが、 日付で集計しなければならないところが難しく感じています。 合計が0(というか対象データが無い場合)の部分は空白でもかまいません。 データベースはOracleですがOracleだけでしか使えない特殊な機能ではなく 普通のSQLの組み合わせで解決したいと思っています。 (でもOracle固有の機能で解決できるのならそれも教えていただきたいです) 基本的に1発のSQLで表形式で帰ってくるSQLの書き方をお願いします。 できれば、SQLそのものを記述していただきたいです。 何回かSQLを発行してあとでエクセルで…とか、他のPG言語でなんとかする という方法は今回はいりません。 よろしくお願いします。

  • SQL 一定期間ごとの集計

    アクセステーブル ---------------------------------------------- 機種 回数 アクセス日時 ------ ---------- ------------------- win 1830 2009/03/16 09:10:10 win 1818 2009/03/16 09:10:13 win 1823 2009/03/16 09:10:21 win 1825 2009/03/16 09:10:24 win 1828 2009/03/16 09:11:51 win 1818 2009/03/16 09:11:53 win 1818 2009/03/16 09:11:54 win 1831 2009/03/16 09:11:55 win 1138 2009/03/16 09:11:57 win 1825 2009/03/16 09:11:58 win 1822 2009/03/16 09:12:02 win 1827 2009/03/16 09:12:04 上記のアクセスログを記録するテーブルがあり、 一分間ごとに下記の集計をしたいのです。(例 : 9:11台) (初回は各分の最初の時間の回数、機種はすべてwin) 機種 アクセス日時 初回 最小 最大 最終 ------ ------------------- ---------- ---------- ---------- ---------- win 2009/03/16 09:11 1828 1138 1831 1825 win    以下、12分台と続きます。 これを抽出するSQLはどう書けばよいのでしょうか? よろしくお願いいたします。 DBはOracle9iです。

  • SQLの構文で質問です。

    いつもお世話になっております。 SQLの構文で質問です。 テーブルを開いて、データの中から日付を絞って抽出したいのですが、 whereの後にどのような記述をすればいいのかわかりません。 なんとなく『>』を使ってやってみましたがうまく抽出できませんでした。 例えば、2008/12/01~2008/12/31の絞りで抽出できるようにしたいのですが。 SELECT * FROM 日付 WHERE (日付   2008 / 12 / 01    2008 / 12 / 31) すみません、SQLを使い始めて間もなく本を見てはいるのですがうまくいかないもので。 宜しくお願いします。

  • SQLでうまいことビューが作れない

    SQLサーバー2005+マネジメントスタジオでビューを作っています。 以下のデータが存在するときに●のついたデータだけを抽出したいです。 明細IDはユニークとし、明細IDの中で一番日付が新しいものだけを取得したいです。 T-SQLでどのように書けばよいか教えてください。 <データ> 明細ID 日付 111 2010/10/01 111 2010/11/01 111 2010/12/01 ● 222 2010/11/01 ● 333 2010/09/01 333 2010/10/01 ● 444 2010/10/01 444 2010/11/01 444 2010/12/01 ● 555 2010/09/01 ● <出力> 明細ID 日付 111 2010/12/01 ● 222 2010/11/01 ● 333 2010/10/01 ● 444 2010/12/01 ● 555 2010/09/01 ●

  • データの件数を集計してTOPを取得するためのSQL

    データの件数を集計して、その結果からもっとも件数が多いものだけを抽出する SQL について教えてください。 例えば以下のようなテーブルがあります。 ▼テーブル 名前 |交通手段|日付 -----+--------+---- Aさん|バス |5/1 Aさん|バス |5/2 Aさん|バス |5/3 Bさん|バス |5/1 Bさん|電車 |5/2 ※「日付」については、本質問に直接の関係はありません。 このテーブルにクエリを発行して、以下の結果を取得したいと考えています。 ▼取得したい結果 (ある交通手段をもっとも使った人を抽出) 名前 |交通手段|回数 -----+--------+---- Aさん|バス |3 Bさん|電車 |1 ※回数が同数の人がいる場合は、「ユーザID」が一番若い人を採用します。  「ユーザID」はこのテーブル例には含まれておりませんが、  「名前」が「ユーザID」であると読み替えてください。 なお、以下の結果を取得するクエリは 質問番号:6719239 にご協力いただけたおかげで解決しました。 SELECT 名前, 交通手段, COUNT(*) AS 回数 FROM テーブル GROUP BY 名前, 交通手段;  ↓ 名前 |交通手段|回数 -----+--------+---- Aさん|バス |3 Bさん|バス |1 Bさん|電車 |1 今回、この結果から 1件目 と 3件目 を抜き出したいと考えております。 プログラム側で対処はできるのですが、SQL の方がスマートに書けそうだと思っております。 なおレンタルサーバ上 (MySQL 5.0.77) で稼働させるため、 なるべく高速な SQL を希望いたします。

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

    ACCESS2000のSQL文について質問です。 K情報テーブル:(支店(テキスト型),所属(テキスト),氏名(テキスト),ログ(テキスト),抽出件数(数値),処理日(日付型)) 支店 所属 氏名 ログ 抽出件数 処理日 ----------------------------------------- 関東 埼玉 太郎 A   50    2009/02/25 関西 大阪 次郎 B   15    2009/04/01 関東 埼玉 太郎 A   10    2009/03/05 関西 大阪 次郎 B   5    2009/04/06 東北 青森 三郎 C   2    2000/01/02 東北 青森 三郎 A   2    2000/01/02 ・ ・ ・ ----------------------------------------- 以上のテーブル情報を、SQL文にて抽出したいのですが、抽出条件が私には難解で解決の見通しが立ちません。ご教授をお願いします。 ***条件*** [ログ] = "A" のみ抽出。 現在日から過去3ヶ月前までのデータのみ抽出。 [氏名]ごと[ログ]の総合計。 [氏名]ごとの[抽出件数]の総合計。 [ログ]の総合計の上位30件を降順で。 順位にNo.をふる。 上記の条件で抽出したデータをを下記の作業テーブルに出力したと思っております。 作業テーブル:順位,所属,氏名,ログ件数,抽出件数 宜しくお願いします。

  • 1つのテーブル内のデータで重複する結果は表示しない

    日付の範囲を2003/10/01 から 2003/10/02 としてコードが重複する場合は1番 新しい日付を抽出す方法はないでしょうか CODE 日付 0001 2003/10/01 0002 2003/10/01 0001 2003/10/02 0001 2003/10/03 0003 2003/10/01 0004 2003/10/10 0005 2003/10/01 のようなデータがあり、検索した結果を CODE 日付 0001 2003/10/03 0002 2003/10/01 0003 2003/10/01 0005 2003/10/01 となるような式はできないでしょうか 使っているdbはSQL Server 6.5 です。  ご享受のほど、お願いします。

  • sql文について教えて下さい

    お世話になっております select文を教えて下さい A   B 123  0 123  0 123  1 123  1 124  0 124  1 124  2 125  0 125  1 125  1 Aの項目でグルーピングしBが0のデータが2件以上あるケースを選択したいのですが良く分かりません。 上記の場合は、A=123のケースだけを選択したいのですが どなたかご教示下さい。 A  B 123  0 123  0 という結果になるようにSQLを組み立てたいのですが よろしくお願いします。

  • デルファイでのSQL文について

    まだ初心者なのでよく分かりません。SQL文について教えてください。 テーブル名:table1 データ:   コード   日付     種類   備考 (1) 1111   2003/12/11  book  AAA (2) 2222   2003/11/10  pencil BBB (3) 2222   2003/12/10  pencil CCC (4) 2222   2003/12/20  cap   DDD 上のようなデータがあった場合、コードと種類が同じで日付が最新のデータを取りたいのですがSQL文でできるでしょうか? 上の場合だと(1)と(3)と(4)のデータを抽出したいのです。GROUP BYですると備考がとれませんでした。 どうぞよろしくお願いします。   

  • これをSQLでやることは可能ですか?

    すいません。どうしても閃かないので教えてください。 まず、テーブルは 連番  PK コード 日付 となっています。 その中のデータは 連番  コード   日付 -----+--------+--------- 1   |   001 | 2002/01 2   |   001 | 2002/02 3   |   002 | 2002/03 4   |   002 | 2002/04 5   |   003 | 2002/05 -----+--------+--------- となっています。 このデータの中から 「コード毎に日付が一番新しい連番」を取得したいのですが可能でしょうか? 結果は 連番   コード   日付 -----+--------+--------- 2   |   001 | 2002/02 4   |   002 | 2002/04 5   |   003 | 2002/05 -----+--------+--------- となって欲しいのですが・・・ どなたかこれを実現するSQLを教えてください。 お願いします。