集計するためのSQL構文を教えて下さい

このQ&Aのポイント
  • 初めて投稿します。集計を行うためのSQL構文について教えてください。
  • データベースはSQLServer2005で、SQL作成環境はSQLServerManagementStudioExpressを利用しています。
  • 想定している出力結果は、指定した日付範囲内で全病室の入院中患者と入院予定患者を病室単位で求めることです。関連するテーブル情報と共に具体的な方法やアドバイスを教えてください。
回答を見る
  • ベストアンサー

集計するためのSQL構文を教えて下さい。

初めて投稿します。よろしくお願いします。 現在、ストアドプロシージャとSQLの勉強をしながら作業を行なっています。そのため説明不足などありましたらご指摘願います。 [環境]  データベース:SQLServer2005  SQL作成環境 :SQLServerManagementStudioExpress(9.00.2047.00) 望んでいる出力結果 病室,タイプ,10/01水,10/02木,10/03金,10/04土,10/05日 -------------------------------------------------------------- 10,集合3,○○太郎,○○太郎,○○太郎,○○太郎,□□花子        △△太郎,△△太郎,□□花子,□□花子        □□花子,□□花子 11,個室A,          ××太郎,××太郎,××太郎 12,個室B,     ○○次郎,○○次郎,○○次郎,○○次郎 ※指定した日付範囲で、全病室を対象に入院中患者、入院予定患者を  病室単位で求めたいです。 関係するテーブル情報 ※マスタテーブルは、名称+Mで表記します。 ※データテーブルは、名称+Tで表記します。 [病室] 病室M(  病室番号 INT  タイプコード INT ) [日付] ストアドのパラメータで集計開始日と終了日を受け取るため、 その集計範囲も動的に変わります。 ※上記の結果では、  集計日(自):2008/10/01  集計日(至):2008/10/05 を受け取った場合を想定し記述しています。 [入院者氏名] 患者T(  患者コード INT  患者氏名 VARCHAR(128)  通院種別 TINYINT(1:通院,2:入院)  退院区分 TINYINT(1:入院,2:退院)  入院日 SMALLDATETIME  退院日 SMALLDATETIME ) [患者と病室を紐付けるテーブル] 病室割当T(  割当番号 INT  患者番号 INT  病室番号 INT ) 長文となり申し訳ありません。 上記の情報でストアドを組もうとしているのですが、 SQL含め勉強不足な状態です。 実現するための考え方、方法、アドバイス等を頂きたいです。 よろしくお願い致します。

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

  • ベストアンサー
  • jamshid6
  • ベストアンサー率88% (591/669)
回答No.1

これは実行結果はExcelやReporting Serviceに流し込むという理解でいいのですよね。 私は毎日のようにこんなのを書いているのですが、いろいろなテクニックが必要なので、少しずつ理解してください。 ・日付テーブルを先に作って、入院期間のデータに増幅します。 ・戻りの列数が固定でないクエリは動的クエリを使って組み立てます。  SQL Server 2005ではvarchar(max)を使います。  動的クエリを使うとクエリが見にくくなるので、必要なデータを一旦テーブルに収録します。  この場合はテーブル変数が使えないため、一時テーブルを利用します。 ・動的クエリにはsp_executesqlを使う方法もあり、パフォーマンスを考慮すればそちらの方がいいのですが、  組み立てがやや面倒なので、EXECを使っています。 (最後にどんなクエリが組み立てられているかは、EXEC(@sql)をprint @sqlに置き換えれば見られます) ・日本語の曜日を求める関数はないので、以下のようにしましたが、利用頻度が高ければスカラー関数を作るのも手です。 ------------------------------------------------------------------------------- CREATE PROCEDURE ap_病室割当一覧(@DATEF smalldatetime,@DATET smalldatetime) AS BEGIN SET NOCOUNT ON DECLARE @WDATE smalldatetime DECLARE @WEEKSTR varchar(20) DECLARE @DATETBL TABLE ([日付][smalldatetime],[曜日][varchar](5)) SET @WEEKSTR = '日月火水木金土' --指定期間の日付テーブルを作成 SET @WDATE=@DATEF WHILE (@WDATE<=@DATET) BEGIN INSERT INTO @DATETBL VALUES (@WDATE,SUBSTRING(@WEEKSTR,DATEPART(dw,@WDATE),1)) SET @WDATE=DATEADD(d,1,@WDATE) END --動的クエリ用にデータを一旦蓄積 CREATE TABLE #MAPDATA ([病室番号][int],[タイプ][varchar](100),[日付][smalldatetime],[患者氏名][varchar](128),[SEQ][int]) INSERT INTO #MAPDATA SELECT bw.病室番号,bt.タイプ,dt.日付,k.患者氏名, ROW_NUMBER() OVER (PARTITION BY bw.病室番号,dt.日付 ORDER BY bw.患者番号) SEQ FROM 病室割当T bw INNER JOIN 病室M b ON b.病室番号=bw.病室番号 INNER JOIN 病室タイプM bt ON bt.タイプコード=b.タイプコード INNER JOIN 患者T k ON k.患者コード=bw.患者番号 INNER JOIN @DATETBL dt ON dt.日付 BETWEEN k.入院日 AND DATEADD(d,-1,k.退院日) --動的クエリを構築して実行 DECLARE @sql varchar(max) SET @sql = 'SELECT 病室番号,タイプ' SELECT @sql=@sql +',MAX(CASE WHEN 日付='''+CONVERT(varchar,日付,111)+''' THEN 患者氏名 END)' +' ['+RIGHT(CONVERT(varchar,日付,111),5)+曜日+']' FROM @DATETBL ORDER BY 日付 SET @sql=@sql+' FROM #MAPDATA' +' GROUP BY 病室番号,タイプ,SEQ' +' ORDER BY 病室番号,タイプ,SEQ' EXEC (@sql) DROP TABLE #MAPDATA END

n_hitomi22
質問者

お礼

返信が遅くなりすいませんでした。 jamshid6さん、解り易いご提示をありがとうございます。 >これは実行結果はExcelやReporting Serviceに流し込むという理解でいいのですよね。 情報提供が少なくすいませんでした。 ストアドプロシージャでの集計結果をActiveReportsへバインドします。 jamshid6さんのご説明で集計ロジックを組む形式(流れ)が初めてながら見えた気がします(6割ほどですが…) 私の方での実行結果は、期待する結果を得ることが出来ましたが、 jamshid6さんからご提示頂いたソースが理解できるよう勉強します。 ご丁寧なアドバイスありがとうございました。 また質問することがあるかと思いますが、今後ともよろしくお願い致します。

その他の回答 (1)

  • jamshid6
  • ベストアンサー率88% (591/669)
回答No.2

#1です。 書き忘れましたが、病室タイプを管理するマスタがなかったので、勝手に想定して足しています。 病室タイプM( タイプコード INT, タイプ INT )

関連するQ&A

  • エクセルでキーワードで集計したい

    指定したセルの中のキーワードで、集計する事はできますか? 例えば「花子」「1,000」     「太郎」「1,500」     「花子」「2,500」     「次郎」「1,000」 とあるときに「花子」をキーにして「3,500」の集計を求める事はできますか?

  • エクセルの集計での質問

    A列に日付、BからF列に担当者名(1~5)が入っています。 この表で誰が何日稼働したか調べたいのですが、日付の被りがあるのと、例えば▲▲さんが「担当者1」、●●さんが「担当者2」と決まっているわけでなく、早いもの順に「担当者1~5」までに名前が入っています。 A B C D E F 日 担1 担2 担3 担4 担5 1/3 太郎 次郎 花子 三郎 和子 1/3 次郎 太郎 三郎 美和 和子 1/4 花子 次郎 孝夫.......... この場合求められたものが 1/3 太郎 ×1、次郎 ×1、三郎×1、花子×1、和子×1 、美和×1 1/4 花子×1、次郎×1、孝夫×1 なので 太郎1日 次郎2日 三郎1日 花子2日 和子、美和、孝夫各1日 という風にエクセルで集計できないでしょうか?

  • SQLの問題です。

    以下のような二つのテーブルがあります。 社員テーブル 社員番号 社員氏名 1     花子 2     太郎 所属テーブル 社員番号 所属番号 1     10 1     20 2     30 欲しいのは以下の結果です。 1 花子 2 太郎 以下のSQLを実行すると、 SELECT distinct a.社員番号, a.社員氏名, b.所属番号 FROM 社員 a,所属 b where a.社員番号 = b.社員番号 order by 所属番号 1 花子 1 花子 2 太郎 となってしまいます。 先に述べたとおりの結果を取得するにはどういうSQLを書いたらいいでしょうか? お知恵を貸してください。宜しくお願いします。 Oracle8iを使用しています。   

  • SQL 集計について

    集計方法がどうしてもわからないのでご教授ください。 下記のテーブルを持っています。 テーブル1では日々の売上金額を管理し、 テーブル2では一週間の日付が保存されています。(月曜日~日曜日) -------テーブル1-------           日付    売上金額   2013/09/01     3000   2013/09/02     4000   2013/09/03     2000    ・              ・           ・           2013/09/30     1000 ----------------------- --------テーブル2---------  日付(月)    日付(日)    2013/08/26   2013/09/01 2013/09/02   2013/09/08    ・        ・    ・       2013/09/30   2013/10/06 ------------------------- テーブル1とテーブル2の情報をもとに テーブル3にある、日付(月)と日付(日)は、テーブル2から持ってきて、 一週間の集計を行いたいと思っております。 --------------テーブル3--------------  日付(月)    日付(日)    売上金額 2013/08/26  2013/09/01     3000 2013/09/02  2013/09/08     6000   ・   ・   ・ 2013/09/30  2013/10/06     1000 ------------------------------------ このようにするにはどのようなSQLを組めばいいのでしょうか? SQL初心者のため、難しい単語などを使わずに ご説明をしていただければと思います。 どうぞ、よろしくお願いいたします。

  • 最新日付のデータを取得したい

    初心者でいまいちSQLが記述できませんでした。 どなたか教えてください。 以下のようなファイルから最新日付のデータを 取得したいのですが、どのようにSQLを記述したら よいかわかりません。 個人番号|日付|名前|生年月日 00000001,2001/1/1,テスト太郎/1960/1/1 00000001,2003/1/1,テスト太郎/1960/1/1 00000001,2004/1/1,テスト太郎/1960/1/1 00000002,2002/1/1,テスト花子/1945/1/1 00000002,2003/1/1,テスト花子/1945/1/1 00000002,2005/1/1,ですと花子/1945/1/1 00000003,2001/1/1,テスト次郎/1980/1/1 00000003,2003/1/1,テスト次郎/1980/1/1 00000003,2005/1/1,テスト次郎/1980/1/1 ↓抽出後 00000001,2004/1/1,テスト太郎/1960/1/1 00000002,2005/1/1,ですと花子/1945/1/1 00000003,2005/1/1,テスト次郎/1980/1/1 よろしくお願いいたします。

  • 次の条件を満たすSQL文をご教示下さい。

    テーブル名: list no | first_name | last_name | comment ----+------------+-----------+--------- 1 | 太郎 | 山田 | ほげ 2 | 次郎 | 田中 | ふが 3 | 花子 | 山田 | ぴよ 4 | 三郎 | 佐藤 | ぴよ 5 | 太郎 | 山田 | ぴよ 6 | 次郎 | 田中 | ふー 7 | 三郎 | 佐藤 | ふー 8 | 花子 | 山田 | ふー 上記の表から同じ”last_name”を持つ人の”first_name”と”last_name”を重複無しで抽出する(下記のような結果)SQL文は作成可能でしょうか。 結果 first_name | last_name ------------+----------- 太郎 | 山田 花子 | 山田 宜しくお願いします。

  • 場合によって条件を変えるSQL

    ORACLE環境下、SQLにて以下のような条件でデータを取得したいです。 AテーブルとBテーブルを結合して、Bテーブルから名称を取得する。 <Aテーブル> id (key) 番号1 番号2 A01  001  n0001 A02  null  n0002 <Bテーブル> code(key) 名前  番号1 番号2 c0001   太郎  001  n0001 c0002   次郎  002  n0002 (1)A.番号が入力されていれば A.番号1=B.番号1 AND A.番号2=B.番号2を条件にする (2)A.番号が入力されていなければ A.番号=B.番号を条件からはずす。 A.番号2=B.番号2 のみで検索する。 <欲しい結果> A01→太郎を取得 A02→次郎を取得 入力されていたら条件に加え、入力されていなかったら 条件から外す、というSQLを教えていただけないでしょうか。 よろしくお願いいたします。

  • 集計を行うSQLについて

    以下の2テーブルの構成で、from_uid毎のto_uidへの在庫移動個数(val)を集計したいと考えています。 ユーザテーブル(user):uid(int), name(string) 在庫移動管理テーブル(zaiko):id(int), from_uid(int), to_uid(int), val(int) たとえば、それぞれ以下のようなレコードがあった場合、 <user> uid, name 1 aaa 2 bbb 3 ccc <zaiko> id, from_uid, to_uid, val 1 1 2 3 2 1 2 5 3 2 1 1 4 3 1 4 結果として、以下を得たいと考えています。 uid=1で検索した場合 to_uid, val 1 0 2 7 3 -4 uid=2で検索した場合 1 -7 2 0 3 0 uid=3で検索した場合 1 4 2 0 3 0 (イメージとしては、対戦表?の以下のような表を一行ずつ取得する様な感じです。) ___1__2__3 1__0__7_-4 2_-7__0__0 3__4__0__0 上記のような結果を得たい場合、どのようなSQLを書けばよいのでしょうか。 内容について、わかりづらい点等がありましたらご指摘ください。

  • エクセルのピボットテーブル集計ごとに印刷

    お世話になります ピボットテーブルでの印刷ですが全体の印刷はすぐに可能ですが 集計ごとの印刷は大変です。 集計ごとに印刷させるVBA等ありましたらよろしくお願いします 太郎 売り上げ|100 交通費 |100 集計 |200 次郎 売り上げ|100 交通費 |100 集計 |200 三郎 売り上げ|100 交通費 |100 集計 |200 上記がピボットとします。 太郎、次郎、三郎同時に印刷させるのではなく A4用紙1枚で太郎の表 A4用紙1枚で次郎の表 A4用紙1枚で三郎の表 と 個々に印刷させたいのですがこんなわがままな印刷ボタンできますか? わかる方ご教授よろしくお願い致します。

  • SQLServerでの複数テーブルからのデータ抽出

    皆様、お知恵を拝借させてください。 現在、SQLServer + VB.netで開発を行っていますが、どうしてもうまくいかないので悩んでいます。 ロジックを組めば解決できるのは、わかっているのですが、SQL文だけで解決したいのです。 よろしくお願いします。 やりたいことは、複数テーブルからの同一IDの抽出です。 IDで単一化 テーブル【現在】を優先して抽出 テーブル【履歴】のみ存在する場合、履歴NOの大きい方を抽出 テーブル【現在】  ID 名前 趣味 ------------------  10 太郎 釣り  20 次郎 ゴルフ テーブル【履歴】  ID 名前 趣味 履歴NO -------------------------  10 太郎 将棋 01  10 太郎 囲碁 02  30 花子 園芸 01  30 花子 料理 02 求めたい結果は 10 太郎 釣り 20 次郎 ゴルフ 30 花子 料理 です。よろしくお願いします。