人力検索はてな
モバイル版を表示しています。PC版はこちら
i-mobile

SQLについて質問です。

データベースの中で、指定した項目の文字個数をカウントしてを保存したいと考えています。

★テーブル名 TEST

★項目名 KOUMOKU1 , KOUMOKU2

例えば テーブル TEST にはデータが20個位入っていて

KOUMOKU1 に りんご という文字が入っているとします。

テーブル TEST には

KOUMOKU1 にりんごと書かれているデータが5個あります。

SQL命令を実行すると

KOUMOKU2 に 5 という数字が入ります。

これを1?20全てのデータに適応させて KOUMOKU2 に全て数字が入る形を作りたいと考えています。

SQL命令がわかるかたおりましたらよろしくお願いします。

※データベースはPhpMyAdminを使用しています。




●質問者: aiomock
●カテゴリ:コンピュータ インターネット
✍キーワード:phpMyAdmin SQL test りんご カウント
○ 状態 :終了
└ 回答数 : 2/2件

▽最新の回答へ

1 ● kn1967
●100ポイント ベストアンサー

【1】更新における制限事項

UPDATE TEST T1
SET KOUMOKU2 = (SELECT COUNT(*) FROM TEST T2 WHERE T2.KOUMOKU1 = T1.KOUMOKU1)

上記のように書けば「いけそうな気がする???♪」などと思うのですが、エラーになります。

UPDATEでは更新されるテーブル(TEST)と同じテーブルをサブクエリ内では指定できないため、

自身(今回であればTESTテーブル)の集計結果を、

自身(同じくTESTテーブル)に書き戻すという動作は一発ではそもそも無理なのです。


【2】対応策その1

以下のように処理を分ければ一応は望みの形になります。

(ステップ1)集計用テーブル(仮にTEST2とする)を空っぽにしておく。

DELETE * FROM TEST2

(ステップ2)集計する。

INSERT INTO TEST2
SELECT KOUMOKU1, COUNT(*) AS KOUMOKU2
FROM TEST
GROUP BY KOUMOKU1

(ステップ3)集計結果を TEST に書き込む。

UPDATE TEST T1
SET KOUMOKU2 = (SELECT KOUMOKU2 FROM TEST2 T2 WHERE T2.KOUMOKU1 = T1.KOUMOKU1 LIMIT 1)

【3a】対応策その1の問題点:時差による誤差の発生

以下のような事が起こりえます。

(ステップ2)集計する。

ステップ2に進むまでの僅かな時間に、

TESTテーブルから「りんご」と入ったレコードが1件消された。あるいは増えた。

(1件だけとは限らない。もっともっと多いかもしれない。)

(ステップ3)集計結果を TEST に書き込む。


ステップ1で集計した時と、ステップ2で書き込むまでの僅かな時差により、

本来得たい結果とは違うものが書き込まれるという事態になってしまう訳ですが、

作っておられるシステムはオークション出品商品の管理が目標であり目的ですから、

この問題をはらんでいる事は大きな問題になりえると思われます。

(「一応は望みの形」と書いたのは、このような問題点を抱えているからです。)


【3b】対応策その1の問題点:複数アクセスによる誤差の発生

間違って集計ボタンを2回クリックしてしまった場合などは、

同じプログラムが2つ動くことになり、しかも、連携は行なっていませんから、

むちゃくちゃなデータが書き込まれたりする可能性があります。


対応としては、

テーブルにロックをかけるなどがありますが、そもそも「対応策その1」自体が、

今件への解決策とは言えず、ロックの話などしだすと話が長くなるだけなので説明は割愛。


【4】対応策その2

対応策というほどのものでもありませんが、

ただ単に、同種のものが何点あるかという事を知りたいだけであれば、

SELECT T1.KOUMOKU1, (SELECT COUNT(*) FROM TEST T2 WHERE T2.KOUMOKU1 = T1.KOUMOKU1) AS KOUMOKU2
FROM TEST T1

といったような具合に、照会をかける度に計算させて、

「照会時点での個数を得る」という形にするほうがよろしいかと思います。

◎質問者からの返答

ご回答ありがとうございます。

問題解決しました。ありがとうございます。


2 ● HALSPECIAL
●35ポイント
UPDATE TEST AS TEST1 SET KOUMOKU2 = (
 SELECT COUNT(1) FROM TEST AS TEST2
 WHERE TEST2.KOUMOKU1 = TEST1.KOUMOKU1
)

こんな感じでSQL1発を期待していますか?

MySQLはUpdate, Deleteで自己相関サブクエリが使えない のでSQL1発では無理です。


PHPでグルグル回しながらセットしていくか、

MySQLだけで完結したいのであれば、

ストアドプロシージャを使うといいです。


あとはテンポラリテーブルを使ってSQL2発で実装するとかです。

◎質問者からの返答

ご回答ありがとうございます。

関連質問


●質問をもっと探す●



0.人力検索はてなトップ
8.このページを友達に紹介
9.このページの先頭へ
対応機種一覧
お問い合わせ
ヘルプ/お知らせ
ログイン
無料ユーザー登録
はてなトップ