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

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

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

Re[5]: SQL文で取得できたりできなかったりする理由は?


(過去ログ 118 を表示中)

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

■69452 / inTopicNo.1)  SQL文で取得できたりできなかったりする理由は?
  
□投稿者/ スライム (1回)-(2013/12/27(Fri) 11:32:01)

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

2013/12/27(Fri) 14:51:52 編集(投稿者)

以下のようなデータベースが既に存在しています。

==T1==
Name
aaa
bbb

==D1==
Num Name Ver Url
1, "aaa, 1, "./file/aaa-001.xls"
2, "aaa, 2, "./file/aaa-002.xls"
3, "bbb, 1, "./file/bbb-001.xls"
4, "bbb, 2, "./file/bbb-002.xls"
5, "bbb, 3, "./file/bbb-003.xls"

==K1==
Num Rev
1, 1
2, 5
3, 1
4, 10
5, 20

以下のSQLにおいて、
※1は取得できますが、※2は取得できません。
どうしてでしょう?

※1
DECLARE @REV INT SET @REV = 9           ←@REV = 9 はOK
DECLARE @Name varchar(10) SET @Name = 'aaa'

SELECT T1.Name, DK1.Num, DK1.Name, DK1.Ver, DK1.Url, DK1.Rev
FROM [MyMaster].[dbo].T1
LEFT OUTER JOIN (
SELECT TOP(1) D1.Num, D1.Name, D1.Ver, D1.URL, K1.Rev
FROM [MyMaster].[dbo].D1
LEFT OUTER JOIN [MyMaster].[dbo].K1 ON K1.Num = D1.Num
WHERE K1.Rev <= @REV
ORDER BY K1.Rev DESC
) AS DK1 ON DK1.Name = T1.Name
WHERE T1.Name = 'aaa'

※2
DECLARE @REV INT SET @REV = 10           ←@REV = 10 はNG
DECLARE @Name varchar(10) SET @Name = 'aaa'

SELECT T1.Name, DK1.Num, DK1.Name, DK1.Ver, DK1.Url, DK1.Rev
FROM [MyMaster].[dbo].T1
LEFT OUTER JOIN (
SELECT TOP(1) D1.Num, D1.Name, D1.Ver, D1.URL, K1.Rev
FROM [MyMaster].[dbo].D1
LEFT OUTER JOIN [MyMaster].[dbo].K1 ON K1.Num = D1.Num
WHERE K1.Rev <= @REV
ORDER BY K1.Rev DESC
) AS DK1 ON DK1.Name = T1.Name
WHERE T1.Name = 'aaa'

1行目以外他は同じSQL文です。
引用返信 編集キー/
■69453 / inTopicNo.2)  Re[1]: SQL文で取得できたりできなかったりする理由は?
□投稿者/ 魔界の仮面弁士 (478回)-(2013/12/27(Fri) 11:57:25)
No69452 (スライム さん) に返信
> 以下のようなデータベースが既に存在しています。
先に前提条件を確認させてください。

まず、各列のデータ型は何ですか?
そして、使用しているデータベース製品は何ですか?


> ==D1==
> Num Name Ver Url
> 1, "aaa, 1, "./file/aaa-001.xls"

テーブル D1 上に
 Num「1」
 Name「"aaa」
 Ver「1」
 Url「"./file/aaa-001.xls"」
なレコードがある、ということでしょうか。
引用返信 編集キー/
■69454 / inTopicNo.3)  Re[1]: SQL文で取得できたりできなかったりする理由は?
□投稿者/ しま (61回)-(2013/12/27(Fri) 12:31:05)
No69452 (スライム さん) に返信
> 以下のSQLにおいて、
> ※1は取得できますが、※2は取得できません。
> どうしてでしょう?

from 句に [MyMaster].[dbo].T1 とあることと、変数名の先頭が '@' だということから SQL Server だろうとは思いますが、
DBMS 名とバージョンやエディションなども示してください。
こういう基本の情報は予め提示して下さい。読み手にあれこれ想像をめぐらせさせる余計な手間を取らせないで欲しいと思います。
また、どのようにして二つのクエリーを実行したのか(コマンドラインツールなのか、SQL Server Management Studio なのかなど)も
示してください。

「取得できません」では出来ないことしかわかりません。
エラーで取得できないのか、結果が 0 件なのか、エラーでも 0 件でもないが期待した結果でないのかはっきりしませんよ。

2つの例を見てみると、二つの変数を定義しておきながら、一つしか使っていませんね
WHERE K1,Rev < @REV の代わりに直接値を指定した場合はどうなんでしょうか?

どうも、 select 文は2つの例で同一のようですがそういうことも説明してくれておれば、いちいち比較しなくて済みます。
あなたの事情がよく判らない他人に質問するんだということをもう少し考えて、おきている事を書いてください。
引用返信 編集キー/
■69455 / inTopicNo.4)  Re[2]: SQL文で取得できたりできなかったりする理由は?
□投稿者/ スライム (2回)-(2013/12/27(Fri) 12:43:18)
2013/12/27(Fri) 12:59:12 編集(投稿者)
魔界の仮面弁士 さん ありがとうございます。

> まず、各列のデータ型は何ですか?
dbo.T1 
   Name(PK, varchar(10), NULL以外)
dbo.D1
   Num(PK, int, NULL以外)
   Name(varchar(10), NULL)
   Ver(int, NULL)
   Url(varchar(50), NULL)
dbo.K1
   Num(PK, int, NULL以外)
   Rev(int, NULL)

> そして、使用しているデータベース製品は何ですか?
> 
Microsoft SQL Server 2008です。
Microsoft SQLSer Management Studio でテストしています。
最終的にMicroosfotVisualStudio 2010 に組み込みます。

引用返信 編集キー/
■69456 / inTopicNo.5)  Re[2]: SQL文で取得できたりできなかったりする理由は?
□投稿者/ スライム (3回)-(2013/12/27(Fri) 12:44:59)
2013/12/27(Fri) 13:22:07 編集(投稿者)
以下のようなテーブル及びデータがすでに入っています。

dbo.T1  dbo.D1                  dbo.K1
┌──┐┌──┬──┬──┬─────────┐┌──┬──┐
│Name││Num │Name│Ver │Url        ││Num │Rev │
├──┤├──┼──┼──┼─────────┤├──┼──┤
│aaa ││  1│aaa │  1│./file/aaa-001.xls││  1│  1│
│bbb ││  2│aaa │  2│./file/aaa-002.xls││  2│  5│
└──┘│  3│bbb │  1│./file/bbb-001.xls││  3│  1│
    │  4│bbb │  2│./file/bbb-001.xls││  4│ 10│
    │  5│bbb │  3│./file/bbb-003.xls││  5│ 20│
    └──┴──┴──┴─────────┘└──┴──┘

すみません。最終行は
  WHERE T1.Name = 'aaa'
ではなくて、
  WHERE T1.Name = @Name
です。

ためしに変数を変えたまま投稿してしまいました。

また、結果は以下の通りです。
@REV = 9のとき
┌──┬──┬──┬──┬─────────┬──┐
│Name│Num │Name│ Ver│Url               │Rev │
├──┼──┼──┼──┼─────────┼──┤
│aaa │   2│ aaa│   2│./file/aaa-002.xls│   5│
└──┴──┴──┴──┴─────────┴──┘
@REV = 10のとき
┌──┬──┬──┬──┬─────────┬──┐
│Name│Num │Name│ Ver│Url               │Rev │
├──┼──┼──┼──┼─────────┼──┤
│aaa │NULL│NULL│NULL│NULL              │NULL│
└──┴──┴──┴──┴─────────┴──┘

@REV = 9のときも 10の時も同じ結果が得られると思うのですが。
┌──┬──┬──┬──┬─────────┬──┐
│Name│Num │Name│ Ver│Url               │Rev │
├──┼──┼──┼──┼─────────┼──┤
│aaa │   2│ aaa│   2│./file/aaa-002.xls│   5│
└──┴──┴──┴──┴─────────┴──┘

引用返信 編集キー/
■69458 / inTopicNo.6)  Re[3]: SQL文で取得できたりできなかったりする理由は?
□投稿者/ shu (460回)-(2013/12/27(Fri) 13:51:42)
No69456 (スライム さん) に返信

> WHERE K1.Rev < @REV
が実は
 WHERE K1.Rev <= @REV
だったり

aaa以外にK1.Rev=9となるデータが入っていたりとか

しませんか?
引用返信 編集キー/
■69459 / inTopicNo.7)  Re[4]: SQL文で取得できたりできなかったりする理由は?
□投稿者/ スライム (4回)-(2013/12/27(Fri) 14:02:47)
2013/12/27(Fri) 14:50:14 編集(投稿者)

データベースのデータの中身は■No69456 で示した通りです。

すみません。
 WHERE K1.Rev <= @REV になってました。

@Name = 'aaa' の場合
以下の2種類しかないので、
@Rev が 5以上なら結果は同じになるんじゃないんですか?

Name Num Name Ver Url Rev
aaa 2 aaa 2 ./file/aaa-002.xls 5
aaa 1 aaa 1 ./file/aaa-001.xls 1



引用返信 編集キー/
■69460 / inTopicNo.8)  Re[5]: SQL文で取得できたりできなかったりする理由は?
□投稿者/ ケージ (1回)-(2013/12/27(Fri) 14:53:40)
LEFT JOINを使っているので、WHERE T1.Name = 'aaa'の条件を満たすものがなければNULLの行が出来ているのではないでしょうか。
K1.Revが10以上のもののNumをD1テーブルで参照すると、Nameが'aaa'のものはないので、SQLは正しく処理をしていると思います。
かなり複雑にLEFT JOINを使っているので、何が問題なのか分かりにくいと思いますが、
とりあえず、サブクエリ等に分割して確認してみては如何でしょうか。

>@Rev が 5以上なら結果は同じになるんじゃないんですか?

貴方がそのようになると思う根拠は何なのでしょうか?
また、質問者がこのような態度はどうかと思いますが、如何でしょうか。
引用返信 編集キー/
■69461 / inTopicNo.9)  Re[5]: SQL文で取得できたりできなかったりする理由は?
□投稿者/ スライム (5回)-(2013/12/27(Fri) 15:03:26)
        ORDER BY K1.Rev DESC
        により
┌──┬──┐ ┌──┬──┐
│Num │Rev │ │Num │Rev │
├──┼──┤ ├──┼──┤
│  1│  1│ │  5│ 20│ ON DK1.Name = T1.Nameに非該当
│  2│  5│→│  4│ 10│ ON DK1.Name = T1.Nameに非該当
│  3│  1│ │  2│  5│ ON DK1.Name = T1.Nameに該当
│  4│ 10│ │  1│  1│ ON DK1.Name = T1.Nameに該当
│  5│ 20│ │  3│  1│ ON DK1.Name = T1.Nameに非該当
└──┴──┘ └──┴──┘

WHERE K1.Rev <= @REVにより
@REV=9 の場合
┌──┬──┐
│Num │Rev │ @Rev=9に該当
├──┼──┤ ↓
│  5│ 20│××
│  4│ 10│××
│  2│  5│○○  → TOP(1) で取得
│  1│  1│○○
│  3│  1│×○
└──┴──┘
       ↑
       ON DK1.Name = T1.Nameに該当

@REV=10 の場合
┌──┬──┐
│Num │Rev │ @Rev=10に該当
├──┼──┤ ↓
│  5│ 20│××
│  4│ 10│×○  → TOP(1) で取得 → ON DK1.Name = T1.Name
│  2│  5│○○    に該当しないのでnullになる
│  1│  1│○○
│  3│  1│×○
└──┴──┘
       ↑
       ON DK1.Name = T1.Nameに該当

と、いうことですよね?
ON DK1.Name = T1.Name で
既にはじかれるのかと思ってたのですが
仕方がないので

LEFT OUTER JOIN (
 SELECT TOP(1) D1.Num, D1.Name, D1.Ver, D1.URL, K1.Rev
 FROM [MyMaster].[dbo].D1
 LEFT OUTER JOIN [MyMaster].[dbo].K1 ON K1.Num = D1.Num
 WHERE K1.Rev <= @REV
 D1.Name = T1.Name   ←これを追加
 ORDER BY K1.Rev DESC
) AS DK1 ON DK1.Name = T1.Name

と、単純に追加してみたのですが・・・
T1.Nameがバインドできないそうです。

ではどうすればよいのでしょうか?

引用返信 編集キー/
■69462 / inTopicNo.10)  Re[5]: SQL文で取得できたりできなかったりする理由は?
□投稿者/ WebSurfer (143回)-(2013/12/27(Fri) 15:17:54)
No69459 (スライム さん) に返信
> 2013/12/27(Fri) 14:50:14 編集(投稿者)
>
> データベースのデータの中身は■No69456 で示した通りです。
>
> すみません。
>  WHERE K1.Rev <= @REV になってました。

一番最初の質問では、

WHERE K1.Rev = @REV

となっていたのを、後から

WHERE K1.Rev <= @REV

に変更しませんでしたか?

そういうことをされると話の流れがおかしくなって、後からこのスレッドを読む人
にとって、わけが分からなくなってしまうのですが。
引用返信 編集キー/
■69465 / inTopicNo.11)  Re[6]: SQL文で取得できたりできなかったりする理由は?
□投稿者/ WebSurfer (145回)-(2013/12/27(Fri) 16:01:33)
No69462 (WebSurfer さん) に返信
> ■No69459 (スライム さん) に返信
>>2013/12/27(Fri) 14:50:14 編集(投稿者)
>>
>>データベースのデータの中身は■No69456 で示した通りです。
>>
>>すみません。
>> WHERE K1.Rev <= @REV になってました。
>
> 一番最初の質問では、
>
> WHERE K1.Rev = @REV
>
> となっていたのを、後から
>
> WHERE K1.Rev <= @REV
>
> に変更しませんでしたか?
>
> そういうことをされると話の流れがおかしくなって、後からこのスレッドを読む人
> にとって、わけが分からなくなってしまうのですが。

すみません、誤記がありました。

最初 WHERE K1.Rev < @REV だったものを、shu さんの指摘を受けて
後で WHERE K1.Rev <= @REV に直したのですよね。

--------------------------------------------------------------------

それはともかくとして、

No69461 (スライム さん) に返信
> @REV=10 の場合
> ┌──┬──┐
> │Num │Rev │ @Rev=10に該当
> ├──┼──┤ ↓
> │  5│ 20│××
> │  4│ 10│×○  → TOP(1) で取得 → ON DK1.Name = T1.Name
> │  2│  5│○○    に該当しないのでnullになる
> │  1│  1│○○
> │  3│  1│×○
> └──┴──┘
>        ↑
>        ON DK1.Name = T1.Nameに該当
>
> と、いうことですよね?
> ON DK1.Name = T1.Name で
> 既にはじかれるのかと思ってたのですが

は思い違いで、

SELECT TOP(1) ... WHERE K1.Rev <= @REV ORDER BY K1.Rev DESC の結果、

4, "bbb", 2, "./file/bbb-002.xls",10

となるので、

SELECT T1.Name, ... FROM [MyMaster].[dbo].T1
LEFT OUTER JOIN 上記結果(4, "bbb", 2, "./file/bbb-002.xls",10)

は、

"aaa", NULL, NULL, NULL, NULL, NULL
"bbb", 4, "bbb", 2, "./file/bbb-002.xls",10

となって、WHERE T1.Name = 'aaa' の条件で、

"aaa", NULL, NULL, NULL, NULL, NULL

という結果になったのだと思います。


> LEFT OUTER JOIN (
>  SELECT TOP(1) D1.Num, D1.Name, D1.Ver, D1.URL, K1.Rev
>  FROM [MyMaster].[dbo].D1
>  LEFT OUTER JOIN [MyMaster].[dbo].K1 ON K1.Num = D1.Num
>  WHERE K1.Rev <= @REV
>  D1.Name = T1.Name   ←これを追加
>  ORDER BY K1.Rev DESC
> ) AS DK1 ON DK1.Name = T1.Name

文法的におかしいかと思いますが。
引用返信 編集キー/
■69466 / inTopicNo.12)  Re[7]: SQL文で取得できたりできなかったりする理由は?
□投稿者/ ケージ (2回)-(2013/12/27(Fri) 16:08:37)
2013/12/27(Fri) 16:18:34 編集(投稿者)

少なくとも、D1とK1はLEFT JOINではなく、INNER JOINにすべきではないでしょうか。
それと、D1.Name = 'aaa'の条件も必要ではないでしょうか。         ←ここを加筆しました。
WHERE T1.Name = 'aaa'の時は、@Rev=9の時も、10の時も、同じ結果が出てほしいのですよね?
引用返信 編集キー/
■69471 / inTopicNo.13)  Re[5]: SQL文で取得できたりできなかったりする理由は?
□投稿者/ shu (461回)-(2013/12/28(Sat) 09:09:40)
No69459 (スライム さん) に返信
> すみません。
>  WHERE K1.Rev <= @REV になってました。
>
> @Name = 'aaa' の場合
> 以下の2種類しかないので、
> @Rev が 5以上なら結果は同じになるんじゃないんですか?

WebSurferさんが説明してくれていますが
私の回答の意図は
@REV=9と@REV=10
で違う結果になる可能性を示したので
私の回答のどちらかに合う状況だと結果は変わります。
引用返信 編集キー/


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

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -