• ベストアンサー
※ ChatGPTを利用し、要約された質問です(原文:ユーザー定義関数作成について教えてください。)

親子関係のテーブルから子供の情報を取得する方法

このQ&Aのポイント
  • 親子関係のテーブルから子供の情報を1フィールド(Tab区切り)で取得する方法について説明します。
  • [MST_table_A] (都道府県マスター)と[TRN_table_B] (名物テーブル)という親子関係のテーブルを例に説明します。
  • マスター1レコードに対して、子供の情報を1フィールド(Tab区切り)で取得するためには、ユーザー関数を作成する必要があります。具体的な方法について説明します。

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

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

スカラー関数自体はパラメータを受け取って、スカラー(今回の場合はvarchar文字列)を返すだけですから説明は不要として、おそらくわかりにくいのは DECLARE @STR varchar(8000) SELECT @STR=ISNULL(@STR+@DELIM,'')+[名物名] FROM TRN_table_B WHERE [都道府県CD]=@PREFCD ですよね? もともとテーブルの値を変数に受けるときに、 SELECT @STR=[名物名] FROM TRN_table_B WHERE ... という書き方をします。 (SET @STR = (SELECT [名物名] FROM TRN_table_B WHERE ...)でもいいですが、MSの今の推奨は上) このとき該当するデータが1件だけならわかりやすいですが、2件以上ある場合、SQL Serverでは検索される順番に「それぞれの行で」@STR=[名物名]が行われます。 例えば上記SELECTの該当が3件で、それぞれ「たこ焼き」、「お好み焼き」、「豚まん」だとしたら、1行読み込むごとに@STRに「たこ焼き」=>「お好み焼き」=>「豚まん」とセットされていき、最後が「豚まん」なので、実行後の@STRは「豚まん」になります。 この性質を利用すると DECLARE @STR varchar(8000) SET @STR='' SELECT @STR=@STR+[名物名] FROM TRN_table_B WHERE ... という書き方ができます。 この書き方をすれば、1行読み込むごとにその行の名物名が足されていくことになるので、実行後の@STRには「たこ焼きお好み焼き豚まん」と入ります。 当然「区切り文字を入れたい」と思いますよね? そこで DECLARE @STR varchar(8000) SET @STR='' SELECT @STR=@STR+','+[名物名] FROM TRN_table_B WHERE ... と書きなおすと、@STRの結果は「,たこ焼き,お好み焼き,豚まん」となります。 区切り文字は入りましたが、先頭にも区切り文字が入ってしまいます。 SUBSTRINGなどを使って先頭の区切り文字を削ってもいいわけですが、ここでもう1つの性質を利用します。 「SQL Serverでは文字列結合の中にNULLが入っていると結合結果もNULLになる」 上の例で「SET @STR=''」と初期値にブランクを指定している理由がここにあります。 (初期値設定がないと@STRはNULLですから、クエリの結果もNULLになってしまいます) 逆にいえば、NULLのときには何を結合しても結果はNULLです。 それで、 DECLARE @STR varchar(8000) SELECT @STR=ISNULL(@STR+',','')+[名物名] FROM TRN_table_B WHERE ... と書けるわけです。 1行目 名物名=たこ焼き @STRはNULLなので、@STR=ISNULL(@STR+',','')+[名物名]の部分は => @STR=ISNULL(NULL+',','')+'たこ焼き' => @STR=ISNULL(NULL,'')+'たこ焼き' => @STR=''+'たこ焼き' => @STR='たこ焼き' 2行目 名物名=お好み焼き @STRは'たこ焼き'なので、@STR=ISNULL(@STR+',','')+[名物名]の部分は => @STR=ISNULL('たこ焼き'+',','')+'お好み焼き' => @STR=ISNULL('たこ焼き,','')+'お好み焼き' => @STR='たこ焼き,'+'お好み焼き' => @STR='たこ焼き,お好み焼き' 以下同じ。 結果、先頭の区切り文字はなく、きれいに想定した結果になるというわけです。 仕組みを理解すると、応用が効きます。文字列加工のかなりのケースでカーソルが不要になります。 ぜひ活用してみてください。

urubou2008
質問者

補足

vb, SQLサーバーで開発をしてきましたが、恥ずかしながらユーザー定義関数と言うものをまだ作成したことがありませんでした。 そんな自分でもこれだけの文で理解することができました! 自分でもこれくらいの説明が人にできるようにがんばっていこうと思います。 最初から最後まで丁寧な解説、本当にありがとうございました。

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

その他の回答 (2)

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

改行はCHAR(13)+CHAR(10)です。 デリミタもパラメータにしておいたのですが、改行は2バイト必要なので、@DELIMの定義を少し変更します。 ALTER FUNCTION GETSTR(@PREFCD int,@DELIM varchar(2)) RETURNS varchar(8000) AS BEGIN DECLARE @STR varchar(8000) SELECT @STR=ISNULL(@STR+@DELIM,'')+名物名 FROM TRN_table_B WHERE 都道府県CD=@PREFCD RETURN @STR END SELECT 都道府県CD,都道府県名,dbo.GETSTR(都道府県CD,CHAR(13)+CHAR(10)) FROM MST_table_A

urubou2008
質問者

補足

昨日まるまるかかりましたが、なんとか仕上げることができました! 本当にありがとうございました。 教えて頂いた関数を調べて考えてみたのですが、正直どういった動作の結果今回の結果を得ることができたのかわかりません。。。。 もしまだ観覧していただけていましたら、解説していただけませんでしょうか? どうぞよろしくお願いします。

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

SQL Server 2000であれば、以下のようにするしかないと思います。 (2005だと、CLR集計関数がまさに目的の処理にはうってつけなのですが) ・1行1クエリを実行することになるので、レスポンスはいいとは言えません。 ・8000バイトが限界なので、長すぎると切れます。 CREATE FUNCTION GETSTR(@PREFCD int,@DELIM char(1)) RETURNS varchar(8000) AS BEGIN DECLARE @STR varchar(8000) SELECT @STR=ISNULL(@STR+@DELIM,'')+[名物名] FROM TRN_table_B WHERE [都道府県CD]=@PREFCD RETURN @STR END SELECT 都道府県CD,都道府県名,dbo.GETSTR(都道府県CD,CHAR(9)) FROM MST_table_A

urubou2008
質問者

補足

求めていた結果がそのまま返ってきました! すごく助かりました! 本当にありがとうございます。 追加で一点質問なのですが、上記[ tab ]を改行にしたいのですが、うまくいきません。。。 何か方法ありますでしょうか?

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

関連するQ&A

  • 「たこ昌」のたこ焼き

    私は生まれも育ちも大阪ですが、よくCMをしている「たこ昌」のたこ焼きを今まで一度も食べたことがありません。というか、もしCMをやっていなければ、その存在すら知らなかったでしょう。 他の関西の皆さんはご存じでしたか? 551の豚まんや、千房のお好み焼きなどは有名で、実際に人気もあるので、大阪名物というのもうなずけるのですが、たこ昌はそんなに有名なのでしょうか? それとも単に私が知らないだけ?

  • INSERTを行う際に別の表のデータを使用する方法について

    Java(Servlet,jsp)、MySQL、Tomcatを使用して開発をしています。 INSERTを行う際に別の表のデータを使用したいのですが、 上手くいきません。 ご教授願いただけますと幸いです。 ■テーブル名:A_mst ■カラム 名前: Name 誕生日: Birthday 都道府県コード: Prefecture_Cd 住所: Address ■テーブル名:B_mst ■カラム 都道府県コード: Prefecture_Cd 都道府県名: Prefecture_Name ■処理内容 パラメーターから取得した「名前、誕生日、都道府県、住所」をA_mstに登録する。 ※A_mstには都道府県列はないため、B_mstから都道府県コードを取得しなければなりません。 String sql = "INSERT INTO A_mst" +"SELECT Prefecture_Name FROM B_mst" +"WHERE Prefecture_Name = Prefecture_Name" +"(Name,Birthday,Prefecture_Cd,Address)" +"values('#1','#2','#3','#4')"; sql = sql.replaceAll("#1",strNname); sql = sql.replaceAll("#2",strBirthday); sql = sql.replaceAll("#3",strPname); sql = sql.replaceAll("#4",strAddress); バージョンは以下になります。 jdk1.6.0_16 Tomcat 6.0 MySQL Server 5.1 何卒よろしくお願いいたします。

  • oracle sqlで先頭の1件を取得

    こんにちはみなさん。 現在、Oracle10gR2を使用しています。 そこで、以下のようなテーブルが存在します。 table_A(明細テーブル) denday | cd | suu | kingaku 2011/03/05 | 1| 1| 1000 2011/03/10 | 1| 2| 2000 table_B(マスタ) cd| henkoday | nm 1 | 2011/03/01| testA 1 | 2011/03/02| testB 1 | 2011/03/06| testC 上記マスタはcd、henkodayで管理しています。 上記table_Aとtable_Bを結合したいと思います。 そこで select t1.* ,t2.* from (select * from table_A order by denday) t1, (select * from table_B order by cd,henkoday desc) t2 where t1.cd=t2.cd and t1.denday>=t2.henkoday とした場合、マスタの3件分、明細データの重複ができてしまいます。 それを、直近の該当マスタのみ参照したいのですが、 以下のようなデータ抽出 table_A(明細テーブル)     table_B(マスタ) denday | cd | suu | kingaku | cd | henkoday | nm 2011/03/05 | 1 | 1 | 1000 | 1 | 2011/03/02 | testB 2011/03/10 | 1 | 2 | 2000 | 1 | 2011/03/03 | testC そのSQLがわかりません。 どうかよろしくお願いします。

  • SQL ServerのINNER JOINについて

    SQL Server 2008 R2のINNER JOINについて質問させて下さい。 ------------------------------ SELECT * FROM [Customer]    INNER JOIN Pref       ON Customer.CustomerPref1 = Pref.PrefId       ON Customer.CustomerPref2 = Pref.PrefId       ON Customer.CustomerPref3 = Pref.PrefId WHERE ([CustomerId] = 123) ------------------------------ 3つもONがあって変なSQL文となっております。 (当然SQLエラーとなります。) やりたい事は、 顧客フォーム[Customer]の中に、都道府県をプルダウン選択する項目が3つあります。 3つとも都道府県マスタテーブルをリレーション(FK)しております。 3つの都道府県項目で「都道府県名」をそれぞれSELECTするには、 どうしたらよいでしょうか? ご教授頂けますようお願い申し上げます。 ------------------ ▼DB情報 顧客情報テーブル:Customer 顧客ID:CustomerId 都道府県カラム1:CustomerPref1(1,2,3,~などの値が格納) 都道府県カラム2:CustomerPref2(1,2,3,~などの値が格納) 都道府県カラム3:CustomerPref3(1,2,3,~などの値が格納) 都道府県マスタテーブル:Pref 都道府県ID:PrefId(1, 2, 3,~などの値が格納) 都道府県名:PrefName(1:北海道, 2:青森県, 3:岩手県~などの値が格納)

  • vb .net Winアプリでコンボボックスに値を

    vb .net Winアプリでコンボボックスに値をセットする方法を教えて下さい。 table1 都道府県コード,都道府県名(カナ),都道府県名 01,ホッカイドウ,北海道 02,アオモリケン,青森県 03,イワテケン,岩手県 のテーブルがあり、既に読み込んでいます。 このデータをコンボボックスにセットしたいです。 Dim NpgsqlConnection1 As NpgsqlConnection Dim NpgsqlCommand1 As NpgsqlCommand Dim NpgsqlDataAdapter1 As NpgsqlDataAdapter Dim String1 As String Dim DataTable1 As DataTable NpgsqlConnection1 = New Npgsql.NpgsqlConnection NpgsqlConnection1.ConnectionString = gstrCnct NpgsqlConnection1.Open() String1 = "select * from table1;" NpgsqlCommand1 = New NpgsqlCommand NpgsqlCommand1.Connection = NpgsqlConnection1 NpgsqlCommand1.CommandText = String1 NpgsqlDataAdapter1 = New NpgsqlDataAdapter(String1, NpgsqlConnection1) DataTable1 = New System.Data.DataTable NpgsqlDataAdapter1.Fill(DataTable1) ' 一括の方法でもOK ' Me.ComboBox1.??? = ???? ' ぐるぐるしながらセットでもOK ' Me.ComboBox1.??? = Space(0) ' Me.ComboBox1.??? = "ミセンタク" ' Me.ComboBox1.??? = "未選択" For Each DataRow1 As DataRow In DataTable1.Rows ' Me.ComboBox1.??? = DataRow1("都道府県コード") ' Me.ComboBox1.??? = DataRow1("都道府県名(カナ)") ' Me.ComboBox1.??? = DataRow1("都道府県名") Next DataRow1 ■要件 メインの情報は都道府県名ですが、 めくった時に 都道府県コード,都道府県名(カナ),都道府県名 を見せる形で作りたいです。 都道府県コードは取り出す必要があります。 データ 1行目は空白,ミセンタク,未選択 2行目以降はtable1から取り出した値。 以上、よろしくお願いします。

  • SQLでフィールドの順番を変更したい

    お世話になっております。 ORACLEを使用しております。 既存のテーブルに新しいフィールドをSQL文にて ALTER TABLE TEST_MST ADD TEST_CD VARCHAR2(2); と言う風に、SQL*PLUSにて追加いたしました。 これを参照しますと、 追加したフィールドがテーブルの一番最後のフィールドに 追加されているのですが、 フィールドの順番を変更したいと考えております。 SQL文にて何か方法はございませんでしょうか。 ご返答を宜しくお願い致します。

  • EXPLAINのtypeがALLのときの対応方法

    先日問い合わせたSQLの高速化についてEXPLAINについて教えて頂きました。 そのEXPLAINについて調べながら試していくと、同じphpファイル内で動かしている いくつかのSQL文に対してEXPLAINのtypeがALLとなっていたので対応すべき SQLだとは分かったのですが具体的にどのようなSQL文に書き換えればいいか 分からなかったので再度質問しました。 前提としてWORDPRESSでSQLをPHPファイル内で$wpdb->get_results関数を使って 実行しています。 (例1) 条件一致した件数を求めるSQL SELECT a_mst.a_id FROM a_mst WHERE a_mst.a_price >= 100 AND a_mst.a_price <= 200 AND a_mst.a_print_flg = 0 SQLのSELECT にCOUNT等は使わない方がいいようなので主キーのみを出力させて count関数で件数を求めています。 このSQL文をEXPLAINでphpMyadminで実行すると id=1       select_type=SIMPLE   table=a_mst type=ALL    possible_keys=NULL   key=NULL key_len=NULL  ref=NUL          rows=a_mstに登録してある件数 Extra=Using where でした。SQL文自体はあるマスタにあるデータから値が100~200のもので、フラグが0のものを 出力するというシンプルなSQL文なのでどう改善すればよいのでしょうか? (例2) 2つのテーブルを結合させて条件一致したデータをそれぞれテーブルから出力 SELECT a_mst.a_name, a_mst.a_price, b_mst.b_data FROM a_mst, b_mst WHERE a_mst.a_id = b_mst.b_id AND a_mst.a_price >= 100 AND a_mst.a_price <= 200 AND a_mst.a_print_flg = 0 ORDER BY a_mst.a_price , a_mst.a_id asc LIMIT 20 OFFSET 0 です。a_mstとb_mstをidで結合させて条件一致したあとにそれぞれの テーブルデータをSELECTしています。実際のSQL文はSELECT させている項目数は多いです。 このSQL文をEXPLAINでphpMyadminで実行すると <1行目> id=1       select_type=SIMPLE    table=b_mst type=ALL    possible_keys=PRIMARY key=NULL key_len=NULL  ref=NUL          rows=a_mstに登録してある件数 Extra=Using temporary; Using filesort <2行目> id=1        select_type=SIMPLE    table=a_mst type=eq_ref    possible_keys=PRIMARY  key=PRIMARY key_len=NULL   ref=b_mst.b_id       rows=1 Extra=Using where でした。 EXPLAINを使ったチューニングなどしたことないSQL低級者なのでどのようなSQL文にすればtypeがALLの場合や、ExtraからUsing temporary; Using filesortを消すことができるのか分からないので教えて下さる方がいましたらよろしくお願いします。 ちなみに、a_mstとb_mstはphpMyadminにてそれぞれのテーブルの「構造」を見ると 「インデックスサイズ」のところで、それぞれの主キーであるa_idとb_idがPLIMARY で登録させています。編集ボタンを押したら「インデックスを修正する」画面に変わるので一応それぞれインデックス登録はされているのかな?と思います。

  • ユーザー定義関数の作成

    1) 基準年の値をP0,t年後の値をPtとした場合の年あたりの伸び率rは、               1/t      r = (Pt/P0)  - 1  で計算されます。 これを計算するユーザー定義関数のVBAを教えてください。 2) 1からnまでの逆数の和  1+1/2+1/3+・・・+1/n=Σ1/i を計算するユーザー定義関数のVBAを教えてください。

  • vb6のコンボボックスの操作について

    おはようございます。 vb6+MDBの環境下で、コンボボックスについて質問です。 マスタとなるテーブルA(都道府県など)と、一般的(?)なデータを日々貯めていくテーブルBがあり、 Bに、Aのキーとなる値が保存されています。 テーブルデータBの表示・更新画面を作っているのですが、 テーブルAの内容を画面上のコンボボックスに選択項目としてADDして表示するところまでは出来たのですが、以下のことを実現するには、コンボボックスにどういう記述で実現するのかわかりません。 1.テーブルBに持っているAの都道府県コードに該当する項目を、Bのデータ選択時に表示したい。 【テーブルA】 Aのキーコード,都道府県名 【テーブルB】 Bのキーコード,Aのキーコード,住所… このような場合、イベント時にコンボボックスをどのように処理するようにソースを書けば実現できますか?

  • PL/SQLにて、マスタから取得した値をORDER BY句に指定したい

    どなたかお判りになる方、ご教示ください。 ★やりたいこと PL/SQLにて、マスタから取得した値をORDER BY句に指定したい。 (例)以下のようなマスタがあるとします。 -------------------------- ソートマスタ SORT_MST ソート順 SORT_ORDER ソート項目 SORT_ITEM ソート種別 SORT_SBT -------------------------- この「ソートマスタ」の「ソート項目」には、以下のトランザクションテーブルの物理カラム名が格納されています。 -------------------------- トラン TRN 商品種別 ITM_SBT 商品コードITEM_COD 商品名 ITEM_NM 金額  ITM_AMN -------------------------- PL/SQLにて「ソートマスタ」から値取得後、「ITEM_COD ASC,ITM_AMN ASC」という文字列を作成し、「トラン」検索時にORDER BY句に指定したのですが、ORDER BY句が全く効いてくれません。 お忙しいところ恐れ入りますが、ご存知の方、よろしくお願い致します。