C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

SQLServer の WITH文の使い方について

[トピック内 8 記事 (1 - 8 表示)]  << 0 >>

■91757 / inTopicNo.1)  SQLServer の WITH文の使い方について
  
□投稿者/ 韋駄天 (13回)-(2019/07/31(Wed) 13:33:02)

分類:[データベース全般] 

2019/07/31(Wed) 13:33:34 編集(投稿者)

SQLServer を使用しています。

以下のままではエラーになります。
--------------------------------------------------
WITH
CTE AS ( SELECT A, B, C FROM DB )
SELECT A
FROM CTE
SELECT B
FROM CTE
SELECT C
FROM CTE
--------------------------------------------------
なので以下のようにWITH文を
すべての前に追加するしかないのでしょうか?
共通で使用することはできないのでしょうか?
WITH文にする必要性がないですよね。
--------------------------------------------------
WITH
CTE AS ( SELECT A, B, C FROM DB )
SELECT A
FROM CTE

WITH
CTE AS ( SELECT A, B, C FROM DB )
SELECT B
FROM CTE

WITH
CTE AS ( SELECT A, B, C FROM DB )
SELECT C
FROM CTE
--------------------------------------------------


引用返信 編集キー/
■91758 / inTopicNo.2)  Re[1]: SQLServer の WITH文の使い方について
□投稿者/ 魔界の仮面弁士 (2266回)-(2019/07/31(Wed) 14:37:49)
No91757 (韋駄天 さん) に返信
> 以下のままではエラーになります。
> --------------------------------------------------
> WITH
> CTE AS ( SELECT A, B, C FROM DB )
> SELECT A
> FROM CTE
> SELECT B
> FROM CTE
> SELECT C
> FROM CTE
> --------------------------------------------------

その構文から、どういう結果を求めているのかという説明が抜けてます…。


とりあえず、

WITH CTE AS ( SELECT A, B, C FROM DB )
SELECT A FROM CTE
UNION ALL
SELECT B FROM CTE
UNION ALL
SELECT C FROM CTE

とか

WITH CTE AS ( SELECT A, B, C FROM DB )
SELECT A FROM CTE
UNION
SELECT B FROM CTE
UNION
SELECT C FROM CTE

ならできますが、そういう事ではない?



> 共通で使用することはできないのでしょうか?

UNION や UNION ALL で 1 回の問い合わせにまとめるのではなく、
3 回の問い合わせそれぞれで、同じ共通テーブル式を使いまわしたい、ということでしょうか。

その場合は、一時テーブルを使うという選択肢もあります。

SELECT A, B, C INTO #IDATEN FROM DB;
SELECT A FROM #IDATEN;
SELECT B FROM #IDATEN;
SELECT C FROM #IDATEN;
引用返信 編集キー/
■91761 / inTopicNo.3)  Re[2]: SQLServer の WITH文の使い方について
□投稿者/ 韋駄天 (14回)-(2019/07/31(Wed) 15:44:13)
No91758 (魔界の仮面弁士 さん) に返信

ありがとうございます。
>3 回の問い合わせそれぞれで、同じ共通テーブル式を使いまわしたい、ということでしょうか。
はい、その通りです。

そのあと、DataSetにデータの取り込みを行います。

一時テーブルを使ってみたのですが
処理に時間がかかったので WITH でできないのかと思ったのですが
無理なようですね。
引用返信 編集キー/
■91770 / inTopicNo.4)  Re[3]: SQLServer の WITH文の使い方について
□投稿者/ 韋駄天 (15回)-(2019/08/01(Thu) 10:09:32)
No91758 (魔界の仮面弁士 さん) に返信

WITHまたは一時ファイルでTESTを作成した場合
TESTのある列のある行でNULLが一つでもある場合はエラーで処理したい。
エラーがなければTEST1のある列をアップデートしたい。

WITH文だとアップデートでTESTは使用できない

一時ファイルを使用するとアップデートができない。

と、いうことです。
引用返信 編集キー/
■91771 / inTopicNo.5)  Re[4]: SQLServer の WITH文の使い方について
□投稿者/ 魔界の仮面弁士 (2271回)-(2019/08/01(Thu) 10:19:01)
2019/08/01(Thu) 10:46:28 編集(投稿者)

No91770 (韋駄天 さん) に返信
> WITHまたは一時ファイルでTESTを作成した場合

一時表なら、#TEST あるいは ##TEST ですね。


> TESTのある列のある行でNULLが一つでもある場合はエラーで処理したい。

一時表に NOT NULL 制約をつけておくだけでは駄目なのでしょうか?

列としては NULLABLE にしておいた上で、後から一時表を
NULL チェックしたいのなら、THROW ステートメントを呼べば OK かと。
SQL Server 2012 未満の場合は RAISERROR ステートメントで。
https://sql55.com/query/raise-error-exception.php


> WITH文だとアップデートでTESTは使用できない

使用できない理由が何かあるのでしょうか?

たとえば下記のような処理は、SQL Server 2008 世代であっても
サポートされていますよね。

WITH CTE AS ( SELECT A, B, C FROM DB WHERE A BETWEEN 1 AND 3)
UPDATE DB2
SET Z = CTE.C
FROM CTE
WHERE DB2.X = CTE.A
AND DB2.Y = ISNULL(CTE.B, CTE.C)


> 一時ファイルを使用するとアップデートができない。

この意味も分からず…。
https://kazenetu.exblog.jp/20171320/

もしかして、ここでいう「一時ファイル」というのは、
いわゆる 一時テーブル とは別の概念なのでしょうか。
引用返信 編集キー/
■91772 / inTopicNo.6)  Re[5]: SQLServer の WITH文の使い方について
□投稿者/ 韋駄天 (16回)-(2019/08/01(Thu) 11:29:31)
No91771 (魔界の仮面弁士 さん) に返信
・WITHの場合
WITH
ABC AS (
SELECT A, B
FROM AB
LEFT OUTER JOIN (
SELECT A, C
FROM AC
) AS AC
ON AC.A = AB.A

UPDATE ABC
SET C = 1

・一時ファイルの場合
SELECT *
INT #ABC
FROM (
SELECT A, B
FROM AB
LEFT OUTER JOIN (
SELECT A, C
FROM AC
) AS AC
ON AC.A = AB.A
) AS ABC

UPDATE #ABC
SET C = 1

#ABC の C は 1 になりますが、
AC の C は変更されない


また、以下のようにしてみたのですが
IF文が使えないみたいです。

WITH
ABC AS 〜

IF (
SELECT COUNT(*)
FROM ABC
WHERE C IS NULL
) > 0
THEN
BEGIN

END
ELSE
BEGIN

END







引用返信 編集キー/
■91773 / inTopicNo.7)  Re[6]: SQLServer の WITH文の使い方について
□投稿者/ 魔界の仮面弁士 (2272回)-(2019/08/01(Thu) 11:59:28)
No91772 (韋駄天 さん) に返信
> ・WITHの場合

何がしたいのかさっぱり分からないです…。


> WITH
> ABC AS (
> 	SELECT	A, B
> 	FROM	AB
> 	LEFT	OUTER JOIN (
> 		SELECT	A, C
> 		FROM	AC
> 		) AS AC
> 			ON AC.A = AB.A
> 
> UPDATE	ABC
> SET	C = 1


・ABC の後の全角空白が文法違反
・最初に出てくる「A」が、AB.A なのか AC.A なのか曖昧で実行できない
・「(」が偶数個で、「)」が奇数個なので、そもそも SQL として成り立たない
・UPDATE に WHERE が無いので、共通テーブル式は無関係で全件更新になってしまう


> #ABC の C は 1 になりますが、
> AC の C は変更されない

そりゃまぁ、AC の C を更新している処理が、どこにも書かれていませんし…。

引用返信 編集キー/
■91782 / inTopicNo.8)  Re[6]: SQLServer の WITH文の使い方について
□投稿者/ 魔界の仮面弁士 (2274回)-(2019/08/01(Thu) 15:02:47)
No91772 (韋駄天 さん) に返信
> また、以下のようにしてみたのですが
> IF文が使えないみたいです。

WITH 共通テーブル式 は、副問い合わせ/サブクエリと同じようなものであり、
SQL クエリの一部としてのみ動作します。
(副問い合わせと違って、WITH では自己参照も可能ですが)

一方、IF はクエリの一部ではなくステートメントです。

IF ステートメント等でオブジェクトとして扱いたいのであれば、
共通テーブル式ではなく一時テーブルやカーソル等の利用を検討してみてください。
引用返信 編集キー/

このトピックをツリーで一括表示


トピック内ページ移動 / << 0 >>

このトピックに書きこむ