• ベストアンサー

通し番号が一番若いレコードの削除

お世話になります。 Linuxを使ってMySQLのレコードが追加された時に自動で処理をする スクリプトを作っています。 データベースはtestで、 データベースのフィールドは、name=varchar(16), password=varchar(16),date=TIMESTAMP, number=int AUTO_INCREMENT となっています。 データを一個ずつ処理したいので、 select Name from test WHERE number=(select MIN(number) from test) としてみた所、上手く希望のデータが取り出せたので、 今度は用がなくなったデータを削除する為に、 delete from test WHERE number=(select MIN(number) from test) としてみたところ、 You can't specify target table 'test' for update in FROM clause と出て、エラーになりました。 エラー内容はサブクエリの結果が変わるようなクエリは発行できないと 言う感じでした。 上手く処理をする方法を思いついたと思ったのですが、このようになって、 どうしたものかと途方に暮れています。 上手く処理をする方法をご存知の方が居られましたら是非御教授いただきたくお願いします。

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

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

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

確かに、こちらの環境でもできないですね。  ちょっと~、、って感じですが・・・・ 参考URLで確認してみると、サブクエリでUpdate,Delete では同じテーブルを使えないと出ています。 何でなのでしょうか?ね? Mysql特有の構文になりますが、Limitで対応できると思います。 delete from test order by number limit 1; これでいけると思います。

参考URL:
http://dev.mysql.com/doc/refman/4.1/ja/subquery-errors.html
sollalice
質問者

お礼

ありがとうございます。 この方法で期待した動作をしました。 ありがとうございます。

その他の回答 (1)

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

SQLをわけていいなら変数をつかって SELECT @MIN_NUM:=MIN(number) FROM test; DELETE FROM test WHERE number=@MIN_NUM;

sollalice
質問者

お礼

ありがとうございます。 分けても上手く処理できるとは思いますが、Linuxのシェルで 一括処理ということで、当方全くシェルを使ったことがない ので、難しい問題を呼びそうなのでできれば分割したくないです。

関連するQ&A

  • phpからquery実行

    趣味でサーバー構築を楽しんでいます phpからqueryでデータを渡そうとしたところ詰まってしまい、どうにも分からないので質問します //MSSQLQuery// DECLARE @acct varchar(32); SET @acct = 'testname'; INSERT INTO test.dbo.tblInfoA (Number,ID,) SELECT Number,@acct FROM test.dbo.tblinfoB WHERE userId = @acct このクエリをphpフォームからDBに送りたく下記をphpに記述しました */php mssql_query("INSERT INTO test.dbo.tblInfoA (Number,ID) VALUES ('SELECT Number FROM test.dbo.tblinfoB WHERE userId = $login','$login');") エラーメッセージ message: Conversion failed when converting the varchar value 'SELECT Number FROM test.dbo.tblinfoB WHERE userId = name' to data type int. (severity 16) お分かりの方いましたらご返答よろしくお願いします。

  • Access2007でSQLの複数列副問い合わせについて

    VB2005+Access2007を使用しております SQL文の複数列副問い合わせについて教えて下さい 検索をしても他のデータベースのものばかりヒットし、解決できません SELECT * FROM Uriage WHERE (Date, DateID) = (SELECT Date, DateID FROM Uriage WHERE NAME = 'cup') これを実行すると 「メイン クエリの FROM 句の予約語 EXISTS を使用しないフィールド を複数返すサブクエリを作成しました。サブクエリのSELECT ステート メントを変更し、1 つのフィールドだけを指定してください。」 というエラーがでてしまいます。 形をかえ、 SELECT * FROM Uriage WHERE Date = (SELECT Date FROM UriageList WHERE NAME = 'cup') AND DateID =(SELECT DateID FROM UriageList WHERE NAME = 'cup') これを実行すると、 「このサブクエリでは 1 つのレコードしか返せません。」 というエラーがでてしまいます。 また、 SELECT * FROM Uriage WHERE (Date) IN (SELECT Date FROM UriageList WHERE NAME = 'cup') AND (DateID) IN (SELECT DateID FROM UriageList WHERE NAME = 'cup') を実行したところ、 エラーはでないものの、抽出結果が異なるものが出てきてしまいました。 これを解決するにはどのようにしたらよいのでしょうか? よろしくお願いいたします。 なお、某知恵袋にも同様の質問をしてしまいましたが、 回答者様への回答や追加質問が出来ず、 こちらに再質問させて頂きました。申し訳ございません。

  • カウント結果を1レコードの中で横に並べたい

    カウント結果を1レコードの中で横に並べたい 以下のテーブルを、 test_table id   group  name 1    100   テスト1 2    100   テスト1 3    100   テスト1 4    200   テスト1 5    200   テスト1 6    200   テスト2 7    200   テスト2 8    200   テスト2 9    200   テスト2 nameごとのカウント、更に100だけのカウント、200だけのカウントといったように、 以下のように横に並べることは可能でしょうか? name   合計  100計   200計 テスト1  5    3      2 テスト2  4    0      4 まず、nameごとの合計を取得するクエリを作って、 それに、100計列、200計列の部分をサブクエリでもってきたのですが、 これで動くには動くんですが、このやり方しかないものでしょうか。 ご教示おねがいします。 SELECT t.name, COUNT(*) as '合計', (SELECT COUNT(*) FROM test_table as t1 WHERE t1.name = t.name AND t1.group = '100' ) as '100計', (SELECT COUNT(*) FROM test_table as t1 WHERE t1.name = t.name AND t1.group = '200' ) as '200計' FROM test_table as t WHERE 1 GROUP BY t.name;

    • ベストアンサー
    • MySQL
  • MySQLのUPDATE文でサブクエリ

    MySQLのUPDATE文でサブクエリの使い方について教えて下さい。 MySQLのUPDATE文でサブクエリを使うと「#1093 - You can't specify target table 'exam' for update in FROM clause 」というエラーになってしまいます。 「あるテーブルに対してデータを追加・更新する場合、同じテーブルをサブクエリーに使えない」 「サブクエリー内のFrom句はテンポラリテーブルとして扱うことが可能」 ということはわかりましたが、これに従いSQL文を変更してもうまくいきません。 どのようにSQL文を作ったら良いか教えていただければと思います。 環境 PHP:5.1.6 MySQL:5.0.77 ------具体的なSQL文--------------------------------------- テーブル名:sample カラム名:date(DATETIME型),name,flag 上記テーブルに対して、 1.社員(列名:nameのsuzuki)の最新出勤日(列名:date)のflagを1にする 2.社員(列名:nameのsuzuki)の最新出勤日以外(列名:date)のflagを2にする という処理をしたいと思います。 まず、SELECT文を作ってみました。 1.最新出勤日データを抽出 SELECT * FROM sample WHERE (date= (select max(date) from sample)) and name='sizili' 2.最新出勤日以外のデータを抽出 SELECT * FROM sample WHERE not (date= (SELECT max(date) FROM sample)) and name='suzuki' これをUPDATE文に変更すると、 #1093 - You can't specify target table 'exam' for update in FROM clause というエラーになります。 上記をUPDATE文に変更 1.最新出勤日データを抽出 UPDATE sample SET flag=1 WHERE (date= (select max(date) from sample)) and name='sizili' 2.最新出勤日以外のデータを抽出 UPDATE sample SET flag=2 WHERE not (date= (SELECT max(date) FROM sample)) and name='suzuki' エラー文を検索したところ下記のような情報を見つけることができました。 「仕事SPOT」 MySQLでサブクエリ(エラー#1093を回避する方法) http://wsjp.blogspot.com/2009/12/mysql1093.html 「あるテーブルに対してデータを追加・更新する場合、同じテーブルをサブクエリーに使えない」 「サブクエリー内のFrom句はテンポラリテーブルとして扱うことが可能」 と記載されています。 このページに掲載してあるように変更を加えてみました。 1.最新出勤日データを抽出 UPDATE sample SET flag=1 WHERE (date= (select max(date) as test_max from sample)) as text_tb and name='sizili' 2.最新出勤日以外のデータを抽出 UPDATE sample SET flag=2 WHERE not (date= (SELECT max(date) as test_max FROM sample)) as test_tb and name='suzuki' これでもエラーになってしまい、うまくいきません。

    • ベストアンサー
    • PHP
  • 最大値を持つレコードを削除したい

    customerテーブル内のprice列の最大値を持つレコードを削除したいのですが、上手くいきません。よろしくお願いします。 DELETE FROM customer WHERE `price` = ( SELECT max( `price` ) FROM customer ) ; エラーメッセージは #1093 - You can't specify target table 'customer' for update in FROM clause と出ます。これは、同じテーブルを参照しているためのエラーのようです。 MySQLのバージョンは、5.0.48です。

    • ベストアンサー
    • MySQL
  • SQL文の実行速度について

    こんにちは。SQLを勉強しています。 質問をさせてください。 Oracleテーブル(test_table:レコード数はかなりあると考えて構いません) にnumber(int),value(varchar), code(varchar)の3つのフィールドが存在 するとします。 今、codeを指定してvalueを取得したいと考えています。 (1)---------------------------- select value from test_table where code='001'; select value from test_table where code='002'; select value from test_table where code='003'; (2)---------------------------- select code, value from test_table where code='001' or code='002' or code='003' (1)と(2)ではどちらが実行速度が速いのでしょうか? 実際に実行すればわかることですが、そういった環境が ないので、確認できません。宜しくお願い致します。

  • 日時を期間指定で出力するには?

    お世話になります。 データベースに、日付VARCHAR(100)というカラムがあり、そこに、"2005/02/01 20:00"のようなデータを登録していっています。これを、指定期間で検索をかけて出力することは可能なのでしょうか。 SELECT * FROM table WHERE BETWEEN '2005/01/01 00:00' and '2005/02/10 00:00'; とします。そのとき、2005/02/01 20:00がヒットできればいいのですが、VARCHAR型で果たしてできるのでしょうか。(正直やってみたのですが、うまくいきません。やはりだめ??) datetime型にすると、2005/02/10 20:00とデータベースにいれると、2005-02-10 20:00:00 となるので、できればVARCHAR型でやりたいのですが。。。 何か方法はないでしょうか。よろしくお願いいたします。

    • ベストアンサー
    • MySQL
  • 副問い合わせの書き方について

    以下のようにテーブルを作成され、データが 格納されています。 CREATE TABLE IDLIST( MAINID number(1), SUBID number(1), FLAG number(1), NAME varchar(10) ); MAINID SUBID FLAG NAME ---------- ---------- -- -------------------- 1 1 1 佐藤様 1 2 0 佐藤さん 1 3 0 佐藤 2 1 1 田中さん 2 2 0 田中 このデータにおいて、FLAGが1であるNAMEをその他の 同一IDにコピーしたいと考えています。 つまり、期待する実行結果は以下のようになります。 MAINID SUBID FLAG NAME ---------- ---------- -- -------------------- 1 1 1 佐藤様 1 2 0 佐藤様 1 3 0 佐藤様 2 1 1 田中さん 2 2 0 田中さん SQL文を以下のように考えてみましたが、 update IDLIST set NAME = ( select NAME from IDLIST where MAINID = ( select MAINID from IDLIST where FLAG = 1) AND FLG = 1 ); この場合はMAINIDが複数のとき、副問い合わせにて 結果が複数あるため、エラーが発生します。 複数返ってくる結果をどのように処理してあげれば よいか困っています。 是非とも1つのSQLで実現させたいと考えています ので、知恵をお貸し頂きたいと思います。 よろしくお願い致します。

  • データ登録時、重複エラーを避けたい

    MYSQLのデータベースの、IDという項目が主キーのTESTというテーブルに、データをに登録する際、 既に主キーが同じデータがない場合に、という条件をつけたいのですが、 下のように書くと、エラーになってしまいます。 INSERT INTO TEST (ID, NAME) VALUES ('a', 'abc') WHERE NOT EXISTS (SELECT * FROM TEST WHERE ID = 'a'); どうしたらよいか教えてください。

    • ベストアンサー
    • MySQL
  • timestamp が空のデータを除いて、データを選択したい

    テスト用に簡単なテーブルを作成してみました。 テーブル名:timetest フィールド: test_id : integer NOT NULL test_date : timestamp without time zone テストデータとして 1,2005-11-15 14:01:40.026 2,NULL 3,2005-11-14 11:11:11.001 このときに test_date がNULL以外のものだけを選択したいのですが、 slect * from timetest where test_date != null; では1件も選択されず、 select * from timetest where test_date != ''; では、 ERROR: invalid input syntax for type timestamp: "" というエラーになってしました。 どなたかご教授お願い致します。