SQLServerのPIVOT絡みの処理でオペランドのデータ型 nvarchar は sum 演算子では無効です

このQ&Aのポイント
  • SQLServerのPIVOT絡みの処理でオペランドのデータ型 nvarchar は sum 演算子では無効です。原因、及び回避策について教えてください。
  • VB6のプログラムからACCESSMDBからデータを取得する処理を、DBを変更してOracleからSQLServerに変更しました。PIVOT相当の処理をSQLで行おうとした際に「オペランドのデータ型 nvarchar は sum 演算子では無効です」という警告が出てしまいます。どのような原因が考えられ、どのように回避すればよいでしょうか?
  • SQLServerのPIVOT絡みの処理で「オペランドのデータ型 nvarchar は sum 演算子では無効です」という警告が表示されます。この警告の原因と回避策について教えてください。
回答を見る
  • ベストアンサー

SQLServerのPIVOT絡みの処理

お世話になります。 従来はVB6のプログラム中で、従来ACCESSMDBからデータを取得していました。 これをDBを変更し、データ自体はOracle、接続先はSQLServer(2005)との仕組みに変更することとなりました。 (SQLServerのリンクサーバ機能にてOracleからデータを取得する) ここで、元のアクセスにて行っていたクロス集計を移行するため 次のようなSQL文(メイン部位以外は端折ってます)を書いたのですが、 「オペランドのデータ型 nvarchar は sum 演算子では無効です」 との警告が出てしまいます。 (”SUM(oraData.suuryou)” を、”Count(oraData.suuryou)”とした場合はデータ取得できました。) 原因、及び回避策についてお知恵を拝借できませんでしょうか? (PIVOT相当の処理をプログラム側で行うことで回避できますが、できればSQLで終えてしまいたいです) SELECT     pvt.moji    ,pvt.moji2    ,SUM([01]), SUM([02]), SUM([03]), SUM([04]), SUM([05]), SUM([06]), SUM([07]), SUM([08]), SUM([09]), SUM([10])     ,SUM([11]), SUM([12]), SUM([13]), SUM([14]), SUM([15]), SUM([16]), SUM([17]), SUM([18]), SUM([19]), SUM([20])     ,SUM([21]), SUM([22]), SUM([23]), SUM([24]), SUM([25]), SUM([26]), SUM([27]), SUM([28]), SUM([29]), SUM([30])     ,SUM([31])  From    openquery  (LinkServerName, '      SELECT        moji       ,moji2       ,hiduke       ,TO_CHAR(hiduke, ''dd'') AS dd       ,hiduke       ,suuryou       ,Sum(suuryou) AS suuryou      FROM        table      WHERE        hiduke BETWEEN TO_DATE(''2008/04/01'', ''YYYY/MM/DD'') AND TO_DATE(''2008/04/30'', ''YYYY/MM/DD'')       UNION      SELECT        moji       ,moji2       ,hiduke       ,TO_CHAR(hiduke, ''dd'') AS dd       ,hiduke       ,suuryou       ,Sum(suuryou) AS suuryou      FROM        table      WHERE        hiduke BETWEEN TO_DATE(''2008/04/01'', ''YYYY/MM/DD'') AND TO_DATE(''2008/04/30'', ''YYYY/MM/DD'')     ') AS oraData PIVOT     (         SUM(oraData.suuryou)         FOR oraData.dd IN           (              [01], [02], [03], [04], [05], [06], [07], [08], [09], [10]              ,[11], [12], [13], [14], [15], [16], [17], [18], [19], [20]              ,[21], [22], [23], [24], [25], [26], [27], [28], [29], [30]              ,[31]            )      ) AS pvt WHERE    moji = "xxx" OR moji2 = "yyy"

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

  • ベストアンサー
  • refinas
  • ベストアンサー率100% (2/2)
回答No.1

自分が参考にしたサイトを記しておきます。 オチは「ストアドでPIVOTを含むSQLを生成し実行」です。

参考URL:
http://blogs.wankuma.com/kaya/archive/2006/09/24/39459.aspx
milletjel
質問者

お礼

ご回答ありがとうございます。 該当ページ参考にさせていただきます。 本件に関して、直接の原因はエラーメッセージ通りsuuryou項目がnvarcharとなっていたためでした。(Oracle上では数値型だったのですが・・・) どうも 1.SQLServerのリンクテーブル機能によるopenquery 2.Oracleとのリンクテーブル機能 3.openquery中での、UNION この3つのいずれか、或いは複合により、取得データの型が全てnvarcharになっていたようです。 今回は、openqueryにて取得したデータに直接PIVOTを使用するのではなく、SQLServer側で一度suuryou項目を数値に変換したものに対してPIVOTを使用することで、目的の値を取得することができました。 (さんぷる) SELECT     pvt.moji    ,pvt.moji2    ,SUM([01]), SUM([02]) ,(略) From    (SELECT      oraData.moji     ,oraData.dd     ,CAST(oraData.suuryou AS numeric(10,0)) AS suuryou    FROM      openquery  (略) AS oraData    WHERE      oraData.moji = "xxx" OR oraData.moji2 = "yyy"    ) AS oraData2 PIVOT     (         SUM(oraData2.suuryou)         FOR oraData2.dd IN           (              [01], [02],(略)           )      ) AS pvt 結局、PIVOTとタイトルをつけるも、それ以外がネックとなっていたようです。 お手数をおかけいたしました。 ※何かしら回答をいただけないと、経過を追記することも、  閉じることもできないのは不便ですね。

関連するQ&A

  • SQLエラーについて

    ora-00907エラー:右かっこがありませんが出ます。なぜでしょうか?? strSQL = strSQL + "select K.Hiduke 日付,S.Syouhinmei 商品名,S.Tanka 単価,K.Suryou 数量,(S.Tanka * K.Suryou) 金額"; strSQL = strSQL + " from SyohinHyo S,Kounyurireki K"; strSQL = strSQL + " where K.Syouhinbangou = S.Syouhinbangou and K.Hiduke"; strSQL = strSQL + " between to_date(" + comboBox1 +",'YYYY-MM-DD') and "; strSQL = strSQL + " to_date(" + comboBox2 + ",'YYYY-MM-DD')";

  • 同じSQL文での検索結果が異なる

    visualbasic2005とoracleを使ってデータベース管理ソフトを作っています。 ひとつのデータのフィールドはいくつかあるのですが、 DATAUPLOADというフィールド値をSQL文で検索するときのみ、 土曜日のデータを拾おうとするとなぜか検索をかけるごとに 件数が1件ずつ減っていくという現象が起きています。 他のフィールドや土曜日以外のフィールドの検索の時には そのようなエラーは起こらないのですが、 同じSQL文で検索結果が随時異なってしまう場合には どのような原因が考えられますでしょうか? DATAUPLOAD は'2008/03/12 00:00:00'の形式のDate型データです。 あるDATE(日付)のデータを検索するときに使用しているSQL文は、 SELECT * FROM DATABASE WHERE DATEUPLOAD BETWEEN TO_DATE(' & CStr(Format(DATE, "yyyy/MM/dd")) & 00:00:00','yyyy/MM/dd hh24:mi:ss') AND TO_DATE(' CStr(Format(DATE, "yyyy/MM/dd")) & 23:59:59','yyyy/MM/dd hh24:mi:ss') です。 いろいろとSQL文を変更してみたのですが、 同じエラーが続いています。 何か思い当たることがありましたら 教えていただければと思います。

  • 日時の期間での抽出

    スケジュール帳のWebアプリを作成していて PostgreSQLを使用しています。 sc_tblというテーブルのday_timeというカラムに日時 to_doというカラムに予定を入れているのですが 日時2006/12/01 01:00のデータを期間の抽出条件で抽出する時 2006/11/30 20:00~2006/11/30 26:00という条件で抽出できるような SQL文はあるのでしょうか。(1:00を25:00として抽出したい) 下記2つのSQLでは無理でした。 ・その1 select day_time, to_do from sc_tbl where day_time >= cast('2006-11-30 20:00:00' as timestamp) and day_time <= cast('2006-11-30 26:00:00' as timestamp); ・その2 select day_time, to_do from sc_tbl where day_time >= to_date('2006-11-30 20:00:00','YYYY-MM-DD H24:MI:SS') and day_time <= to_date('2006-11-30 26:00:00','YYYY-MM-DD H24:MI:SS');

  • WHERE句でのデータ型について

    お願い致します。 ORACLEのWHERE句に対する疑問点ですが、 カレンダを管理するテーブル(カレンダマスタ)において、条件を指定してデータをSELECTする時にWHERE句に記入するデータ型についてご指導お願いします。 <詳細> 目的としてカレンダマスタよりSYSDATEの年月の休みの日を除く、稼動日数(COUNT)を求めるのが、目的です。 自分で作成した、SQLでは目的を果たしているのですが、WHERE句にTO_CHARを使用し、抽出項目(年月日-DATE型)を指定しているのですが、条件を指定する時は、TO_CHARで指定しても問題は無いのでしょうか? <SQL> SELECT COUNT(TO_NUMBER(休みFLG)) AS 稼動日 FROM カレンダマスタ WHERE 年月日 BETWEEN (TO_DATE(LAST_DAY(ADD_MONTHS(SYSDATE,-1))+1,'YYYY/MM/DD')) AND (TO_CHAR(LAST_DAY(SYSDATE),'YYYY/MM/DD')) AND 休みFLG='0' <補足> 休みFLG='0'は稼動日

  • SQL Server 2005 Expressを利用して1ヶ月前のデータを表示する方法について

    SQL Server 2005 Expressを使って、テーブル(tbl出席簿)に格納され たデータのうち、今日よりも1ヶ月前のデータを表示するSQL文を教え てください。 因みにAccessでは SELECT tbl出席簿.名前,tbl出席簿.日付,Format([日付],"yyyy/mm/dd") AS 1ヶ月前 FROM tbl出席簿 WHERE (((Format([日付],"yyyy/mm/dd"))=Format(DateAdd("m"-1,Date()),"yyyy/mm/dd"))); でOKなんですが、SQL Server 2005 Expressを使った方法がわかりませ ん。 どうか、御教示下さる様宜しくお願いいたします。

  • 【SQL】複数行から最大値の取得

    以下のSQLを実行すると ENDDATE      PNO 2013/02/01 00000001 2013/02/01 00000002 2013/02/03 00000001 2013/02/01 00000003 2013/02/05 00000002 2013/02/01 00000001 2013/02/02 00000002 の様になります。 これを ENDDATE      PNO 2013/02/03 00000001 2013/02/01 00000003 2013/02/05 00000002 の様にENDDATEの最大値のみを残しPNOが重複しないものを抽出したいです。 以下のSQLをどの様に修正すれば可能でしょうか? ==SQL================================================== SELECT CO1.ENDDATE,AD1.PNO FROM COMMON CO1,ADMADMISSION AD1 WHERE CO1.DETAILOF IN ('10') AND AD1.CURRENTWARD=:CURRENTWARD AND CO1.STARTDATE BETWEEN TO_CHAR(TO_DATE(:CURRENTDATE)-:ENDLINE,'YYYY/MM/DD') AND TO_CHAR(TO_DATE(:CURRENTDATE)+:DEADLINE,'YYYY/MM/DD') UNION SELECT CO2.ENDDATE,CO2.PNO FROM COMMON CO2,ADMADMISSION AD2 WHERE CO2.DETAILOF IN ('10') AND AD2.CURRENTWARD=:CURRENTWARD AND CO2.ENDDATE BETWEEN TO_CHAR(TO_DATE(:CURRENTDATE)-:ENDLINE,'YYYY/MM/DD') AND TO_CHAR(TO_DATE(:CURRENTDATE)+:DEADLINE,'YYYY/MM/DD') UNION SELECT CO3.ENDDATE,CO3.PNO FROM COMMON CO3,ADMADMISSION AD3 WHERE CO3.DETAILOF IN ('10') AND AD3.CURRENTWARD=:CURRENTWARD AND :CURRENTDATE BETWEEN CO3.STARTDATE AND CO3.ENDDATE

  • SQLコマンドの「TO_DATE」について

    SQLコマンドで、下記を実行すると「2014/04/03」などが取得できると思ったのですが、 「14/04/03」で取得してしまいます。 (aaa_dateは、DATE型で、「2014/04/03」などが入ってます) select TO_DATE(aaa_date,'YYYY/MM/DD') from AAA_TBL YYYYをYYにして、下記を実行すると、なぜか、「2014/04/03」と正常に取得します。 select TO_DATE(aaa_date,'YY/MM/DD') from AAA_TBL 逆の気がするのですが、なぜでしょうか。

  • TIMESTAMPを検索するフォームを設けたい

    HTMLで上下にフレーム分割し、 ・上段が検索フォーム ・下段が問い合わせ結果のリストアップ、 という構造があるのですが、MYTIME (timestamp(14))という フィールドの検索フォームはどのように設けるのが一般的でしょうか。 例えば、 ・7月1日以降にデータが更新されたレコードのみ抽出、 ・今日の12:00以降に更新されたレコードのみ抽出、のように用いたいです。 MYTIMEには、 20051221080904 20060701194647 などのレコードがあります。 timestampでなく、date型なら、↓のように、 yyyy-mm-dd、yyyy/mm/dd、yyyymmdd書式で問い合わせができることを経験してます。 select myfield,mytime from myfield where mytime >= '20060714' select myfield,mytime from myfield where mytime >= '2006/07/14' select myfield,mytime from myfield where mytime >= '2006-07-14' そのとき、検索フォームは <input type="text" name="date_more" maxlength="10" title="yyyy-mm-dd、yyyy/mm/dd、yyyymmdd書式で入力">以降 <input type="text" name="date_less" maxlength="10" title="yyyy-mm-dd、yyyy/mm/dd、yyyymmdd書式で入力">以前 ・・などとしました。 今回のTIMESTAMP型も、↑と同じでいけますか? 年月日と時分秒は分割したほうがよかったりするのでしょうか? そうすると、SQL文に渡す前に、年月日.時分秒 のようにくっ付けて WHERE条件に加えることになりますよね? 標準的な方法をご教示ください。

    • ベストアンサー
    • PHP
  • oracle sqlについて

    お世話になります。 Oracle Sqlでの質問を致します。 Oracleのデータで重複データを削除したく 下記の構文を書いたのですが、 右括弧がありませんと言うエラーが出てしまいます。 見た目括弧はちゃんとあると思うのですが、 どこが悪いのか分かりません。 ご親切な方、ご教示くださいます様、 宜しくお願いいたします。          記 DELETE FROM D入庫データ WHERE ID NOT IN ( SELECT MIN(ID) FROM D入庫データ GROUP BY PPID,台車番号,入庫数量,ロット番号,TO_CHAR(登録日時,'yyyy,mm,dd') WHERE TO_CHAR(SYSDATE,'yyyy/mm/dd)=TO_CHAR(登録日時,'yyyy/mm/dd') );

  • select文について

    SQLで情報を抽出しようとしています。 情報はFAX受信枚数です。 select distinct count(*)from <datebase A> where <page_no>='6' and to_char(receive_date,'yyyy/mm/dd') between 'YYYY/MM/DD' and 'YYYY/MM/DD'; 上記の構文だと、PAGE 6/6のついでに PAGE6/8なども一緒くたに情報を引っ張ってくると思われます。 今回知りたい情報はPAGE 6/6の受信枚数のみ なのですが、どうすれば条件に当てはまる式になるでしょうか。 なお、情報項目には、6/6を示す情報はありません。