• 締切済み

ON DUPLICATE KEY UPDATE

3ヶ月の集計結果を、QWERTYのPKとかぶらないものだけインサートします。 ただし、PKとかぶったものの中でも、QWERTYのCNT1が0のレコードについては、 QWERTYのCNT1のみ集計結果をアップデートしようとしています。 しかし、「~」部分の「ON DUPLICATE KEY UPDATE・・・」を挿入した際に、 エラー(ERROR 1111 (HY000): Invalid use of group function)となってしまいます。 <SQL文> INSERT IGNORE INTO QWERTY( PHOGE, J, MHOGE, SHOGE, CNT1, CNT2, CNT3, NDATE, YMO ) select TEST.PHOGE, TEST.J, 'ABCD', TEST.SHOGE, sum(TEST.m1cnt) AS M1, sum(TEST.m2cnt) AS M2, sum(TEST.m3cnt) AS M3, '2014-07-01' , TEST.YMO from ( select PHOGE, J, SHOGE, SUM(OD_CNT) AS m1cnt, 0 AS m2cnt, 0 AS m3cnt, YMO from HUJIKO WHERE CARD = '1' AND (KHOGE = '1' OR KHOGE = '9') AND (ODATE LIKE'2014-07%') group by PHOGE, J, YMO UNION select PHOGE, J, SHOGE, 0 AS m1cnt, SUM(OD_CNT) AS m2cnt, 0 AS m3cnt, YMO from HUJIKO WHERE CARD = '1' AND (KHOGE = '1' OR KHOGE = '9') AND (ODATE LIKE'2014-08%') group by PHOGE, J, YMO UNION select PHOGE, J, SHOGE, 0 AS m1cnt, 0 AS m3cnt, SUM(OD_CNT) AS m3cnt, YMO from HUJIKO WHERE CARD = '1' AND (KHOGE = '1' OR KHOGE = '9') AND (ODATE LIKE'2014-09%') group by PHOGE, J, YMO ) AS TEST GROUP BY TEST.PHOGE, TEST.YMO, TEST.J ON DUPLICATE KEY UPDATE CNT1=if(CNT1=0, TEST.M1 , CNT1); ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 「ON DUPLICATE KEY UPDATE 」で実現不可能であれば、 他の方法を取りたいのですが、 なるべく一つのSQL文で実現可能な方法をとりたいと考えています。 ご教示の程よろしくお願いいたします。

  • MySQL
  • 回答数2
  • ありがとう数1

みんなの回答

  • yambejp
  • ベストアンサー率51% (3827/7415)
回答No.2

>QWERTYテーブルは、5つのカラム(PHOGE, MHOGE, J, YMO, NDATE)でユニーク として、この5カラムのユニーク属性を利用するならON DUPLICATEで処理だし それ以外でユニーク処理をしたいならテーブルの制限がつかえない以上 SQLを1文でやるのはそこそこ厳しい そもそもPKってのがよくわからないのですが?

Kamen_Ride
質問者

補足

PKは、プライマリキーです。 よろしくお願いします。

  • yambejp
  • ベストアンサー率51% (3827/7415)
回答No.1

おなじテーブルを再現できないのでなんともいえませんが QWERTYテーブルのPHOGEにUNIQUE属性がついているということでよろしいですか? UNIONしているくだりが無駄な気がしますのでこんなかんじでしょうか? INSERT INTO QWERTY( PHOGE, J, MHOGE, SHOGE, CNT1, CNT2, CNT3, NDATE, YMO ) select PHOGE , J ,'ABCD' , SHOGE , SUM(OD_CNT*(ODATE LIKE'2014-07%')) AS M1 , SUM(OD_CNT*(ODATE LIKE'2014-08%')) AS M2 , SUM(OD_CNT*(ODATE LIKE'2014-09%')) AS M3 , '2014-07-01' , YMO from HUJIKO WHERE CARD = '1' group by PHOGE, J, YMO ON DUPLICATE KEY UPDATE CNT1=if(CNT1=0, TEST.M1 , CNT1);

Kamen_Ride
質問者

補足

>おなじテーブルを再現できないのでなんともいえませんが >QWERTYテーブルのPHOGEにUNIQUE属性がついているということでよろしいですか? →QWERTYテーブルは、5つのカラム(PHOGE, MHOGE, J, YMO, NDATE)でユニークになっています。 >UNIONしているくだりが無駄な気がしますのでこんなかんじでしょうか? →はい提示の通り、そんなかんじです。 (具体的に言いますと、 HUJIKOテーブルから、7, 8, 9月それぞれの集計結果をUNIONで縦に出し、名前をTESTテーブルとします。 その後、「GROUP BY TEST.PHOGE, TEST.YMO, TEST.J」で横に(1レコードに)まとめている処理です。 今回聞きたい内容からすれば冗長ですね失礼しましたm(__)m ) 引き続き、よろしくお願いします。

関連するQ&A

  • 集計関数の合計について

    お世話になります。 SQLSever2005を使用しています。 Count(*)で月毎のデータ件数を集計し、またその結果を出力するSQLを考えております。 SELECT  (SELECT Count(*) FROM TBL_TEST T1 WHERE T1.T_DATE>='2005/01/01' AND T1.T_DATE=<'2005/01/31') AS CNT_1,  (SELECT Count(*) FROM TBL_TEST T2 WHERE T2.T_DATE>='2005/02/01' AND T2.T_DATE=<'2005/02/31') AS CNT_2,   (SELECT Count(*) FROM TBL_TEST T3 WHERE T3.T_DATE>='2005/03/01' AND T3.T_DATE=<'2005/03/31') AS CNT_3,   (CNT_1+CNT_2+CNT_3) AS TOTAL_CNT ・・・・・・・・・・・・ (★)  FROM TBL_TEST T  WHERE ・・・・・・・・・ 結果(★)のところで『CNT_1は無効です』というエラーになってしまいます。 ちなみにAccessではエラーにならずに結果を出力していました。 上記のSQL文はどのように修正すればよろしいでしょうか?

  • Access 2000 サブクエリとJOIN

    Access2000でSQLを発行したのですが、 エラーが出てしまいます。 テーブル(仮にtest1、test2)があるとして test1 ------------------------- 主キー | 番号|項目    1|  1|りんご    2|  2|ぶどう    3|  3|みかん    4|  4|いちご test2 ----------------------------- 一つ目|二つ目| 1| 2| 4| 1| ・・・略 test2には2つのフィールドがあり、1,2,3,4を既定値として 入れるようにしています。 やりたいとこは、test2をグループ化し「一つ目」と「二つ目」 の規定値の個数(1、2、3、4)それぞれのカウントを求めたいのです。 一つのフィールドの場合は、 select * from test1 join test2 test1.番号=test2.一つ目 group by test1.番号 で求められたのですが、二つのフィールドをグループ化した際、 一つ目のフィールドと同じ個数が二つ目のフィールドにコピーされてしまうのです。 ですので、FROM句でサブクエリを結合しその中で、 group化したものを、いくつかのサブクエリと結合し てみたのですが、うまくいきませんでした。 select cnt1.一つ目,cnt2.二つ目 from (select * from test1 left join test2 on test1.番号=test2.一つ目group by test1.番号) as cnt1 left join (select * from test1 left join test2 on test1.番号=test2.二つ目group by test1.番号) as cnt2 on cnt1.番号=cnt2.番号 といった形で作ってみました。 エイリアスをつけてしまった時点でエラーが出ているので、 どうにもしようがありません。 申し訳ないのですが、ご教授のほどよろしくお願いいたします。

  • 複数の副問合わせにて、一つだけデータがない場合の対処法は?

    テーブルの各区分に応じて、数量を個々に集計するSQLを作成しております。 そして以下のようなSQLを作りました。 SELECT TBLA.SURYO_1 ,TBLB.SURYO_2 , TBLC.SURYO_3 ,TBLD.SURYO_4 FROM (SELECT SUM(SURYO) AS SURYO_1 FROM TEST_TABLE WHERE TEST_KUBUN = '1' GROUP BY SURYO) TBLA, (SELECT SUM(SURYO) AS SURYO_2 FROM TEST_TABLE WHERE TEST_KUBUN = '2' GROUP BY SURYO) TBLB, (SELECT SUM(SURYO) AS SURYO_3 FROM TEST_TABLE WHERE TEST_KUBUN = '3' GROUP BY SURYO) TBLC, (SELECT SUM(SURYO) AS SURYO_4 FROM TEST_TABLE WHERE TEST_KUBUN = '4' GROUP BY SURYO) TBLD しかし、この方法ですと、区分'1','2','4'はデータがあるのに対して、区分'3'は データがないことにより、SQLを実行すると、対象データがないという結果となります。 当然個別にSQLを実行すればよいですが、速度的に4回もSQLを実行するのは効率悪いので、 出来れば一回で行いたいのですけど、区分'3'がデータがなくても、他の3つの区分のデータ を取得する方法はありますでしょうか? よろしくお願いします。

  • ON DUPLICATE KEY UPDATE

    こんにちは。 PHP + MYSQL でシステム構築をしております。 この度は、新しいレコードを INSERT するが、もしもINSERT するレコードのうちの主キーが既に存在する場合は、UPDATE を行うという処理をしたいと思っています。 調べているうちに MySQL 4.1.0 の新機能である ON DUPLICATE KEY UPDATE 節というものがありましたが、4.1.0以前の MYSQL を利用の場合はどのようにするのが最適でしょうか? 私が考えたのは、挿入前に主キーを持つレコードを読み込んで、レコードが返ってこなかった場合は INSERT、何かレコードが返ってきた場合は UPDATE というようにする方法ですが、少し回りくどい気もします。 クエリのみで、またはシンプルな方法でこれを解決する方法はありますでしょうか? ご教授お願いいたします。

    • 締切済み
    • PHP
  • MySQL4でViewの代わりにできますか?

    PostgreSQLで下記のようなビューを作成し、そのビューから日付でgroupbyして日付ごとのユニーク件数を取っていました。 ---------------------------------------------- create view v_uniqcountday as select substring(datetime, 1, 8) as date, uniqid, careercd, count(*) as cnt from accesslog group by date, uniqid, careercd order by date; select date, count(*) as cnt from v_uniqcountday where (date >= xxx) and (date < xxx) group by date; ---------------------------------------------- しかし、MySQLではViewは作成できないようです。 そこでselect文のみで上記のような集計は可能でしょうか? よろしくお願いいたします。

  • VBA 行の先頭で数値判定しその列の書式を変たい

    エクセルVBA初心者です。 12~20行目の先頭(4列目)が数値か判定し、数値であれば、10~12列目の数式を書き換えるようにしたいのですが、IsNumeric判定がうまく機能せず、全ての行の数式を書き換えてしまいます。 どなたか理由が分かる方がおりましたらご教示頂けます様、お願い致します。 Dim myROW, m1, m2, i As Integer Worksheets("1").Activate For i = 12 To 20 myROW = i m1 = 1 m2 = 2 If IsNumeric(Cells(myROW, 4)) = True Then Cells(myROW, 10) = "=ROUND(SUM(J" & m1 & ":J" & m2 & "),0)" Cells(myROW, 11) = "=ROUND(SUM(k" & m1 & ":k" & m2 & "),0)" Cells(myROW, 12) = "=ROUND(SUM(l" & m1 & ":l" & m2 & "),0)" Else End If Next

  • SQL文で作ったデータを使ったUPDATE

    環境はMySQL5.6です。 下記のテーブルccがあります。 【cc】 shisan  user 500  tanaka 1000  mikami 400   tanaka 1300  mikami SELECT Total, user FROM (SELECT SUM( cc.shisan ) AS Total, user FROM cc GROUP BY user) AS t1 とすることによりSQL上にt1テーブルを作ることが出来ます。 【t1】 Total  user 900  tanaka 2300  mikami 次に、このt1テーブルのTotalの数値を下記のmoney_tableにあるcash欄に挿入(UPDATE)したいと考えています。 【money_table】 cash  user 0   tanaka 0   mikami そこで下記のSQL文を作ったのですがエラーになります。 UPDATE money_table,cc SET money_table.cash=t1.Total FROM (SELECT Total, user FROM (SELECT SUM( cc.shisan ) AS Total, user FROM cc GROUP BY user) AS t1) WHERE money_table.user=t1.user どこがいけないのかご指導いただけませんでしょうか? よろしくお願いいたします。

    • ベストアンサー
    • MySQL
  • SQL count 別名を条件に使用

    いつもお世話になっております。 標題についてご教授頂きたく質問させて頂きました。 [SQL} select A, B, count(*) as cnt from product where A=1 and cnt > 2 group by A order by cnt desc とこのようにSQLを記述して実行したのですが、 cnt>2でエラーが出ます。 order by には count の別名を使用できるのですが、 where句やHAVINGでは使えません。 この場合 cont(*)>2 またはcount(項目名)>2 としなければならないのでしょうか

  • UPDATEで困っています

    下記の2つの表があり、 表Aから伝票番号毎に集計したTAXで、 同じ伝票番号をもつ表BのTAXを、一括更新しようと考えています。 表Bについては、伝票番号の中で最小の明細番号の行のみ 更新しなければなりません。 SQL-SERVERでは、下記のSQLでどうやら大丈夫そうなのですが、 Oracleでは、更新どころかエラーが発生してしまい、 途方に暮れています。 どなたか、ご教授頂けないでしょうか? よろしくお願い致します。 update B set 税額 = AA.税額合計 from B inner join (select 伝票番号, min(明細番号) as 最小明細番号   from B group by 伝票番号) as BB on BB.伝票番号 = B.伝票番号 and BB.最小明細番号 = B.明細番号 inner join (select 伝票番号, sum(税額) as 税額合計 from A group by 伝票番号) as AA on AA.伝票番号 = B.伝票番号 (表A) ・伝票番号 ・明細番号 ・TAX (表B) ・伝票番号 ・明細番号 ・金額 ・TAX

  • シンプルなSQLの書き方がわかりません。

    以下のSQLをシンプルに一つにしたいのですが、どのように書いたらよろしいでしょうか? どうぞご返答頂けますようお願い申し上げます。 --test1_tblの抽出 select a1 as a1, b1 as b1 from a_tbl where c=1 --test2_tblの抽出 select a1 as a1, e1 as e1 from b_tbl where rowid in (select min(rowid) from ee group by a1) and a1 is not null and a1 !=' ' order by a1 --test1_tblとtest2tblの結合 select t0.a1 as a1, t0.b1 as b1, t1.e1 as e1 FROM test1_tbl t0, test2_tbl t1 WHERE (t0.a1 = t1.a1)