视图中的 'UNION' 是怎莫了 ???(50分)

  • 主题发起人 陈荻秋
  • 开始时间

陈荻秋

Unregistered / Unconfirmed
GUEST, unregistred user!
MSSQL6.5中明确规定视图中不允许用UNION关键字.
我曾经违反这一规定,并成功建立了一个UNION多个
表的视图.但是基于此视图的任何查询,只要带有OR
条件查询/统计的就会出错(得到错误百出的结果集!!!)
那位大侠能解释一下???
 
也许union并不能生成view吧(或者生成的view本身就不全或有错的). 只是返回和
select相同的结果, 让你以为建立view成功了. 再次查询时用到的view是个不正确
的view. 当然错误百出了.
(以上结论属瞎猜的)
 
也许??
有没有数学上的依据?
 
要为瞎猜的东西找依据还真有点困难
 
顺便说明:
1: 视图已经被MSSSQL6.5接受并可以用Enterprise Manager管理.
2: 之所以这样用,是为了基于多个表的统计编程方便.这一功能可以
说是很必要的,但是SQL为什么不支持呢?
 
因为:
union只是一种简化复杂条件的子select语句.
所有union都可以用复杂条件的子select(或多句select)代替.
所以:
union并不是必要的.
 
我也用Union作过视图,没问题。
但还真的没用过OR子句进行查询,待明天试试 :)
 
dwwang:
用 AND 没有问题.

Another_eYes:

所有?恐怕未必!
以我现在的问题为例:
****************************************
设备(包括a,b,c三个类别)的参数分别以三个表A/B/C保存
a设备的规格用 a1 表示
.....状态用 a4
b设备的规格用 b1,b2 联合表示 !!
.....状态 b4
c设备的规格用 c1,c2,c3 联合表示 !!
.....状态 c4

以上规格字段的名字,类型,长度,数量 各不相同,联合表示的意义是相同的.
状态字段名字不同,其它相同
------------------------------------------

对于给定的上述条件,完成以下功能
按 状态和规格 分组统计设备数量(注意:不分设备类别)

******************************************

或许有其它的解决办法,望不吝赐教!
 
陈荻秋:

不妨把你的View的定义贴出来看看
(就是针对你上面这个例子的)
 
  问题简化一下

**** 表和视图的定义  ***
//A类设备
CREATE TABLE dbo.A
(
ID numeric(18, 0),
GG1 char(15) NULL,
ZT char(8)
)
//B类设备
CREATE TABLE dbo.B
(
ID numeric(18, 0),
GG1 int NULL,
GG2 int NULL,
ZT char(8)
)
//视图定义
CREATE VIEW MyView
AS
select ID,
'A' as LB,
GG1 as GG,
ZT
from A
union
Select ID,
'B' as LB,
convert(char(8),GG1)+convert(char(8),GG2) as GG,
ZT
from B

********** 基于视图的查询例子和结果集如下 ************
select * from myview
ID LB GG ZT
---------------------- -- ---------------- --------
1 A aaa 000A
1 B 34 43 000A
2 A aaa 000B
2 B 22 21 000B
3 A abcd 000C
4 A cdef 000A
5 A 2221 000B
(7 row(s) affected)
正确!

select * from Myview where (zt='000A')
ID LB GG ZT
---------------------- -- ---------------- --------
1 A aaa 000A
1 B 34 43 000A
4 A cdef 000A
(3 row(s) affected)
正确!

select * from Myview where (gg='aaa')AND(zt='000A')
ID LB GG ZT
---------------------- -- ---------------- --------
1 A aaa 000A

(1 row(s) affected)
正确!

select * from Myview where (gg='aaa')OR(zt='000A')
ID LB GG ZT
---------------------- -- ---------------- --------
1 A aaa 000A
1 B 34 43 000A
2 A aaa 000B
2 B 22 21 000B
3 A abcd 000C
4 A cdef 000A
5 A 2221 000B

(7 row(s) affected)
错误!!!
A表和B表中都有满足条件的记录,SQL却把所有的A表B表记录都选出!!!
为什么??
 
Another_eYes:
你的说法有点道理,但是具体如何实现才好呢?

我使用 CASE 也能实现从不同的表选择不同的字段合成一个表
但是效率及其低下,如上例的三个表几乎是无条件的连接.
 
这主要是因为SQL6.5 不支持带union的View 或是内部隐含支持但存在一些问题.
你可以试试用SQL6.5 的Service Pack 3 or 4 or 5 修补后看看是否还有错误,
经测试,在SQL7内部新版上结果完全正确
 
补充一点,SQL7文档说明支持带Union 的View
 
难道真的是 BUG
SQL7 没有试过,待我试试再说

顺便问一下,Download SP 那个站点比较快
 
我只知道微软有,另外SQL7 Beta3光盘上有SQLServer6.5 SP4
 
问题没有满意答复,烂摊子也不摆下去了.
收摊了!!!
哪位有较好的解释请EMail给我.我将另奉50分

chendiqiu@163.net
 
多人接受答案了。
 
为什么ACCESS中用到UNION的视图,在用TTable打开时不能见到string类型的字段
(FieldDefs中string类型的字段.Size=0),而用TQuery(SQL.text='select * from myview')则能见到所有字段,但string类型的字段的Size均变为255,
能在TTable的情况下解决此问题吗?
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
D
回复
0
查看
1K
DelphiTeacher的专栏
D
D
回复
0
查看
766
DelphiTeacher的专栏
D
D
回复
0
查看
1K
DelphiTeacher的专栏
D
顶部