こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

SQLで一行更新したい

 こんにちは。
今、SQLの勉強をしている初心者です。
データの1~30までの件数に、NUMBER1~30を入れたいのですがどうすればいいでしょうか?

例えば、
      X     Y       NUMBER
     GHU    KJI        0
     HUG    EER       0
     HUU    OPI        0

上記にあるNUMBERを下記のようにしたいです。

      X     Y       NUMBER
     GHU   KJI        1
     HUG   EER        2
     HUU   OPI        3

UPDATE文だと一列全部変わってしまいます。
どのような文を作ればいいのかよく分からないでいます。
よろしくお願いします。

投稿日時 - 2013-02-08 11:55:39

QNo.7934328

すぐに回答ほしいです

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

>クエリをそのまま実行しました。
とありますが、その後ろには
>この'dbo'というのはWITH句の前にある文に含まれているのですが、
と書いてありますよね。

これはそのまま実行したとはいえません。
どうしてその前のステートメントは開示していただけないのですか?(dboのキーワードがそのステートメント内にあるのですよね)
ちなみにWITHステートメントは調べていただけましたか。
私はクエリも書きましたが検索していただくことを推奨してますが・・・
WITHステートメントを調べれば、このステートメントのスコープについてかかれており、直前・直後のステートメントでは
セミコロンが必要なことも明記されています。

>入れてみましたがダメでした。
前回と同じなのか、別のエラーなのか、やはりこれではフォローできません。

ちなみに今回の事例のような場合、普通はNo.3のnharasawaさんのおっしゃるとおりfetchで処理していくのが一般的です。
update一文で処理をすれば、その意図がみえづらくなり後々困ることになるからです。

投稿日時 - 2013-02-10 19:01:16

お礼

ありがとうございます。
返答がだいぶ遅れました。
いったん出直してこようかと思います。

投稿日時 - 2013-03-25 11:40:49

このQ&Aは役に立ちましたか?

1人が「このQ&Aが役に立った」と投票しています

回答(7)

ANo.6

エラー内容のとおりwith句の前の文末にセミコロンをいれたら駄目なのでしょうか?

投稿日時 - 2013-02-09 19:41:52

お礼

入れてみましたがダメでした。

投稿日時 - 2013-02-10 17:33:47

ANo.5

仮にテーブル名を「T」として、
・X,Yで一意になる。
・順番はX,Yの昇順につける。
を前提にすれば
create table T
(
X varchar(3),
Y varchar(3),
[number] int
)
insert into T values ( 'GHU', 'KJI', 0 );
insert into T values ( 'HUG', 'EER', 0 );
insert into T values ( 'HUU', 'CPI', 0 );
update T
set T.[number] = Q.rn
from
T inner join
( select X,Y, row_number() over( order by X, Y ) as rn from T ) as Q
on T.X=Q.X and T.Y=T.Y

で対応できるはずです。
前提が違う場合は(X,Yで一意にならないなど)、別のやり方が必要でしょう。

投稿日時 - 2013-02-09 17:31:18

ANo.4

まず、前提として、XとYの文字列昇順(ABC順)の番号を NUMBER カラムに格納したいという事でよろしいでしょうか?
また、1~30までは変更して31番目以降は元のままということで良いでしょうか?

もし、そうだとすると下記の様なUPDATE文を書けば良いかと。

1. サブクエリで対象の行以前の行の数を取り出し NUMBER カラムに設定する
2. ただし、31以上の場合は元の値を設定する


例) ------------------------------------
UPDATE target_table SET
NUMBER = (
SELECT CASE WHEN COUNT(*) <= 30 THEN COUNT(*) ELSE a.NUMBER END
FROM target_table b WHERE b.x < a.x OR b.x = a.x AND b.y <= a.y
)
FROM target_table a;
----------------------------------------

もし、この前提が間違っていましたら、割振る番号についてのルールなどを提示して下さい。

投稿日時 - 2013-02-09 15:23:32

ANo.3

1個のUPDATEでは出来ないので、CURSORと番号の変数をDECLAREで宣言し、FETCHで1件づつ読み出し、番号をカウントアップしながら、UPDATEで1件づつの処理をレコードの終わるまで繰り返します。

投稿日時 - 2013-02-09 10:02:54

お礼

カーソルを作成し、FETCH処理を行うやりかたでもいいんですね。
カーソルとFETCHはまだ勉強途中なので今度試してみようと思います。

投稿日時 - 2013-02-09 19:19:31

ANo.2

発行した更新クエリと、エラー内容を書いていただけないと、フォローのしようがないです。

投稿日時 - 2013-02-08 23:00:02

お礼

Senna_FFさんの書いたクエリをそのまま実行しました。
テーブル名は変更してあります。
しかし、エラーで

メッセージ 336、レベル 15、状態 1、行 7
'dbo' 付近に不適切な構文があります。これが共通テーブル式の場合は、前のステートメントをセミコロンで明示的に終了してください。

とエラーがでます。
この'dbo'というのはWITH句の前にある文に含まれているのですが、どうやらWITH文からしておかしいと判断しているように思えるのですが、どうでしょうか?

投稿日時 - 2013-02-09 19:15:13

ANo.1

「SQL Server UPDATE CTE」「SQL Server ROW_NUMBER()」 でそれぞれWeb検索してみてください。
これら機能の組み合わせ(CTEとROW_NUMBER())で実現可能かと思われます。


仮にテーブル名を<TestTable>とすれば、下記のように・・


WITH cte_TestTable AS (
SELECT *,
ROW_NUMBER() OVER(ORDER BY X ASC) AS ROW_NUM
FROM TestTable
)
UPDATE cte_TestTable
SET NUMBER = ROW_NUM

投稿日時 - 2013-02-08 17:09:18

補足

了解しました。
早速、試してみます。

投稿日時 - 2013-02-08 18:10:17

お礼

失礼しました。
当方では、SQL Server2005を使用しております。
上記の文法ではエラーがでるのですが、何故でしょうか?

投稿日時 - 2013-02-08 18:28:54