数値を単一引用符で囲む意味とは?

このQ&Aのポイント
  • 数値を単一引用符で囲む理由について、疑問に思ったことを質問します。
  • 数値を単一引用符で囲む必要性について説明します。
  • 数値を単一引用符で囲むと囲まないの違いについてお知らせください。
回答を見る
  • ベストアンサー

数値を単一引用符で囲むのはどういう意味がある?

ちょっと疑問に思ったことがあるので質問です。 例えば以下のようなselect文があるとします。 (keyというカラムはint型です) select * from hogehoge where key = 1; これでselectは問題なく出来るのですが、以下のように値を単一引用符で囲っても、やはりselectは可能でした。 select * from hogehoge where key = '1'; カラムの型が文字列であれば単一引用符で囲まなくてはいけないですが、数値は逆に単一引用符で囲ってはいけないとばかり思っていました。 数値を単一引用符で囲むのと囲まないのとでは、何が違うのでしょうか?御存知の方、教えて下さい。

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

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

PostgreSQLの独自仕様のようです。 '1'は数値でなく文字なのですが、数値との型変換を自動的に行ってくれるようです。 以下の操作を試して、定数の型を確認してみました。 (1)select 1→int4 (2)select 1.→numeric (3)select '1'→unknown (4)select '1'::int→int4 (5)select 1::dec→numeric (6)select 'A'→unknown '1'だけ入力した場合は、'A'と同じ、つまり文字として認識されています。 C1がdecで、「where C1=1」と指定した場合、内部的にはint→decの型変換が行われています。 この場合、型変換を行わせないためには、「where C1=1.」と指定する必要があります。 これと同様に、PostgreSQLでは、「where C1='1'」と指定した場合、文字→intの型変換が行われています。 型変換はオーバーヘッドになりますので、できるだけ列の型にあった定数を指定した方がいいというのが、どのDBMSにも共通の常識だと思います。 PostgreSQLでは、文字から数値への自動的な型変換も行ってくれるようですが、型変換のオーバヘッドがある上、見た目だけで判断すると、列のデータ型を勘違いすることになり兼ねないので、こういった使用は行わない方がいいと思います。

yamyamyam
質問者

お礼

詳しいご説明をありがとうございました。''で括った場合は、第一義的にはunknownなんですね。それを内部的に型変換してintに直していると。これは確かにオーバーヘッドですね。勉強になりました。 Postgresの話とちょっとズレるのですが、例えばPHPのPEAR::DBクラスでプレースホルダーを使って、 $sth = $dbh->prepare("select * from hoge where key = ?"); $sth->query($sth, array(1)); とやると、実行時のクエリーは、 select * from hoge where key = '1' というものが生成されていました。これは、自動型変換を前提にしたクエリーが生成されているという事ですよね。 PHPに限らず、プレースホルダーは値のエスケープに便利なのですが、自動型変換のオーバーヘッドを考えると、少なくとも数値型にはプレースホルダーは使用しない方がいいのかな、と思いました。 その辺り、chukenkenkouさんはどう思われますでしょうか?(質問ばっかりですみません・・)

関連するQ&A

  • version7,version8 の型の扱い

    PostgreSQL の 7 から8 へマイグレーション作業をしている者です。 int型で not null制約のあるカラム「id」 の値から、''(空)であることを判定する時、 version7 では、 $sql = "select * from tbl_name where id <> ''"; のSQL文で動いていたようですが、 version8 では、 型の扱いが厳しくなった訳か、syntax error となります。 この場合version8 では、 $sql = "select * from tbl_name where id <> 0"; が、 ''(空)であることを判定するSQL文と考えてよいでしょうか? ご教授よろしくお願いします。

  • CONCAT内の数値が、別の長い数値に変換されます

    お世話になります。 MySQL5をphpMyAdminで利用しています。 フィールド項目の属性が文字列(VARCHAR)の際には表示OKなのですが、 以下のような数値フィールド属性(BUN_CODE、およびBUN2_CODE)だと、 SELECT文を実行した際に もともと入っている正しい数値ではなく、 なぜか、別の長い数値(意味不明の長い数値)に、 変換されて表示されてしまいます。 SELECT concat(  case when  a.`BUN_CODE`<>b.`BUN_CODE` then ""  else a.`BUN_CODE`   end,    case when  a.`BUN2_CODE`<>b.`BUN2_CODE` then ""  else a.`BUN2_CODE`   end  ) AS DMYDATA FROM (  SELECT * FROM `DMY_TABLE`  WHERE `ID_CODE`=12345 ) AS a, (  SELECT * FROM `DMY_TABLE`  WHERE `ID_CODE`=67890 ) AS b; 質問内容ですが、 数値属性のフィールドに対しては、 何か付け加えないと、上記の場合には、 正しい値を表示出来ないのでしょうか? 以上になります。 情報をお持ちの方がいらっしゃいましたら、 ぜひ教えてください。 よろしくお願いいたします。

    • ベストアンサー
    • MySQL
  • 結合したテーブルに名前をつけるには?

    お世話になります。 【前提】 Aテーブル |key|hoge|int1|int2| (keyはユニーク) Bテーブル |key|hogehoge| (keyはユニーク) 上記のテーブルを、下記のSQLで結合。 SELECT `A`.`key`,(`A`.`int1` / `A`.`int2` ) as `kekka`, `B`.`hogehoge` From `A` left join `B` on `A`.`key` = `B`.`key` 【目的】 ユニークではない`A`.`hoge`の重複を省き、かつ、`kekka`が最大のものを選びたい。 【考え方】 `A`.`hoge`でグループ化し、max(`kekka`)を選ぶ。 【そのために】 SELECT `A`.`key`,(`A`.`int1` / `A`.`int2` ) as `kekka`, `B`.`hogehoge` From `A` left join `B` on `A`.`key` = `B`.`key` IN(SELECT max(`kekka`) FROM `●●` GROUP BY `A`.`hoge`) ★質問です。 1)根本的に足りてない知識は何でしょうか? 2)上記の考え方で間違っていませんか? 3)●●には何を入れればよいでしょうか? (`A`を指定してみましたが、Unknown column 'kekka' in 'field list'といわれてしまいました) MySQLのバージョンは5.1.57です。

  • 副問合せで複数列の値リストの作り方

    言葉で表現するよりも、サンプルのSQL文で分析してもらう 方が理解しやすいと思いますので、そのやり方で進めさせて もらいます。 実際にやりたいことは、 select * from example1 where (key1, key2) in (select key1, key2 from example2); の値リスト版になります。 もちろん、上記のselect文での副問合せでは正常に結果は得られます。 実際にやってダメだった例は select * from example1 where (key1, key2) in ((値A-1, 値A-2), (値B-1, 値B-2), (値C-1, 値C-1)); のようなパターンになります。 単にカッコで括ったリストにすればいいというものではないと判断できる のですが、複数列の副問い合わせ文の値リストはどう表現すればよいのでしょうか? プログラムを作る際、key1とkey2の連結されたものの集合で それを実現する必要があるのですが、困り果てて、以下のように key1とkey2を連結してから問い合わせさせるようにして、その場を しのいでおります。連結されたものを再度key1とkey2に分割して 目的の副問い合わせをさせるのが狙いです。 select * from example1 where (key1 || key2) in (値1, 値2, 値3); これでも十分結果は得られるのですが、key1、key2にせっかくインデックス を作っていても連結しての問い合わせはその効果は得られず、結果を得る までの所要時間が相当かかってしまうのが欠点です。できるだけ高速に 検索できるようにしたいのが今回の狙いなのですが、今回の件の記述方法 についてのアドバイスをお願いします。

  • フィールドの値が数値かどうか調べる

    varchar(2)のフィールドがあります。 値は必ず二文字入力されています。 値が数値の時は数値以外かを判断できますか? (用途) コンボボックスのソースに下記の様に指定したいのです。 select * from T_品種 where 品種コード 「が数字だったら」 よろしくお願いします。

  • ERROR 1054 (42S22) 原因不明です

    idはintでプライマリー a5はchar(10)で日本語文字列を格納 データを取得しようとすると#1054エラーがでます。 admin-------- SELECT * FROM `aaa` WHERE `a5`=`あいうえおかき` #1054 - Unknown column 'ã moniter-------- mysql> SELECT * FROM `aaa` WHERE `a5`=`あいうえおかき`; ERROR 1054 (42S22): Unknown column '縺ゅ>縺・∴縺翫°縺・ in 'where clause' `あいうえおかき`の日本語に問題があると思い半角データを1行だけ更新しました。 admin-------- SELECT * FROM `aaa` WHERE `a5`=`abcde` #1054 - Unknown column 'abcde' in 'where clause' moniter-------- mysql> SELECT * FROM `aaa` WHERE `a5`=`abcde`; ERROR 1054 (42S22): Unknown column 'abcde' in 'where clause' admin-------- moniter-------- SELECT * FROM `aaa` WHERE `a5` SELECT `a5` FROM `aaa` WHERE 1 SELECT * FROM `aaa` WHERE `id`=89584 成功

    • ベストアンサー
    • MySQL
  • WHERE カラム名 <> ''の意味

    $result = $db->query("SELECT カラム名 FROM テーブル名 WHERE カラム名 <> ''"); PHPでSQL文を作成しているサンプルがあるのですが、「WHERE カラム名 <> ''」の意味が分かりません。カンマ二つで空文字? これはどういう意味でしょうか? また、<>は何と読むのでしょうか?(検索したいので)

    • ベストアンサー
    • MySQL
  • DELETE文とロックについて

    DELETEしようとしているレコードがロックされている場合は、削除せず すぐに処理を戻したいです。イメージ的にNOWAITが最適と思い →DELETE FROM テーブルA WHERE カラムA = 'A' NOWAIT としたいところですが、NOWAITはSELECT文でしか指定できないとのことなのでNGです。 SELECT文で抽出した条件のレコードを削除する場合 →DELETE FROM テーブルA WHERE カラムA =      (SELECT カラムA FROM テーブルA WHERE カラムA = 'A') と出来ます。 又、SELECT文でロック待機時間なしの場合 →SELECT カラムA FROM テーブルA WHERE カラムA = 'A' FOR UPDATE NOWAIT と出来ます。 これらを組み合わせて、ロックされているレコードを削除しようとした場合、 すぐにNGで制御を戻すように、次のように記載してみました。 →DELETE FROM テーブルA WHERE カラムA =    (SELECT カラムA FROM テーブルA WHERE カラムA = 'A' FOR UPDATE NOWAIT) なぜかNGになってしまいます(右カッコがありませんと言われます)。 なぜこの書き方が出来ないのでしょうか? 現在、一度該当のレコードをSELECT文でFOR UPDATE NOWAITをしてから DELETEをしています。 1つレコードを削除したいだけなのに、わざわざSELECT文と DELETE文を発行してしまっています。 こういう場合、他にどのような方法があるのでしょうか? 宜しくお願いします。

  • テキスト型に入れた値を数値に変換し、「#エラー」を

    テキスト型に入れた値を数値に変換し、「#エラー」を0にしたいです。 access2003です。 テーブル1を ・テキスト型 ・主キーなし として データを 1 2 あ を投入します。 そして SELECT CLng(テーブル1!フィールド1) AS 数値型に変換 FROM テーブル1; クエリを作りました。 このクエリを開くと 1と2は数値に変換されますが、文字列を入れた「あ」は 「#エラー」になります。 「#エラー」を0にしたいのですが どうすえばいいのでしょうか?

  • MySQLで検索されたフィールド

    いつもお世話になっております。 MySQLで以下のようなSQL文を発行しています。 select * from table where (INSTR(`table`.`name`,'キーワード')<>0 OR INSTR(`table`.`keyword`,'キーワード')<>0) nameカラムとkeywordカラムのどちらのカラムから検索されたのか知りたいのですが どのようにしたらよろしいでしょうか。 (「キーワード」文字列がどちらのカラムに入っているのか知りたいです。) [環境]  MySQL:5.5.16 よろしくご教示お願いいたします。

    • ベストアンサー
    • MySQL