请教写一个SQL语句的写法,实现一种效果。

JRQ 2008-07-26 04:14:43
源于一个想法,需要写一个SQL语句来实现,但没有成功。
即:把表2中的一行数据,作为表1新增的一列显示出来。(行列的数目是对应的)

举例如下--------

表1内容:
ENFIELD CHNAME
A 序号1
B 序号2
C 序号3
D 序号4
E 序号5
... ...

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

表2内容:
A B C D E ......
值1 值2 值3 值4 值5 ......

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

要求SQL查询得到如下效果:把表2中的一行数据,作为表1新增的一列(VALUES)显示出来。

ENFIELD CHNAME VALUES
A 序号1 值1
B 序号2 值2
C 序号3 值3
D 序号4 值4
E 序号5 值5
... ... ...

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

在此向各位请教。

如果用SQL_Server能实现,那么用Oracle又如何写呢?

多谢了!
...全文
394 36 打赏 收藏 转发到动态 举报
写回复
用AI写文章
36 条回复
切换为时间正序
请发表友善的回复…
发表回复
JRQ 2008-07-29
  • 打赏
  • 举报
回复
多谢楼上各位了!

为了同时适应SQLSERVER和Oracle的需求,最后还是选择了在前台寄主中循环拼写完成SQL。

采用的是UNION ALL的方式。

在寄主完成SQL的拼写,我所想到的,大致有两个好处吧:

1.SQL字符串长度不受限制,能解决诸如SQLSERVQR中的varchar(8000)限制。
2.不使用存储过程或函数,这样就能同时适应于SQLSERVER和Oracle的需求,方便系统移植。

缺点是可能会造成速度\效率降低一些。(我在JAVA中都append,实际运行效果还行吧。^_^)


我所拼写的SQL就是用的楼上各位提供的方法,可以通用于SQLSERVER和Oracle。

最终拼写完成后的SQL大致的样子如下:

Select ENFIELD,CHNAME,VALUE From t1 a INNER JOIN
(
Select 'A' as ID,(select RTrim(A) from t2 ) as VALUE FROM t2 --此处可以增加where条件
union all
Select 'B' as ID,(select RTrim(B) from t2 ) as VALUE FROM t2
union all
Select 'C' as ID,(select RTrim(C) from t2 ) as VALUE FROM t2
--如果有,继续拼接
......
) b
on a.ENFIELD=b.ID
and ((ENFIELD='A'and VALUE='值1') or (ENFIELD='C'and VALUE= '值3')) --过滤条件。


---------

再次表示感谢。

尤其对npkaida 和 fcuandy 。 :)
npkaida 2008-07-28
  • 打赏
  • 举报
回复

if object_id('t1') is not null
drop table t1
go
create table t1(ENFIELD char(1), CHNAME varchar(10))
insert into t1
select 'A', '序号1' union all
select 'B', '序号2' union all
select 'C', '序号3' union all
select 'D', '序号4' union all
select 'E', '序号5'

if object_id('t2') is not null
drop table t2
go
create table t2(A varchar(10), B varchar(10), C varchar(10), D varchar(10), E varchar(10))
insert into t2
select '值1', '值2', '值3', '值4', '值5'

DECLARE @sql VARCHAR(8000)
SELECT @sql=ISNULL(@sql + ' UNION ALL ','') +
'SELECT ENFIELD=''' + name + ''',[VALUES]=(SELECT TOP 1 ' + name + ' FROM t2)'
FROM syscolumns
WHERE id=object_id('t2')
print @sql
EXEC('SELECT a.ENFIELD ,a.CHNAME,b.[VALUES] FROM t1 a'+
' INNER JOIN (' + @sql + ') b ON a.ENFIELD=b.ENFIELD'+
' where (a.ENFIELD=''A'' and b.[VALUES]=''值'') or (a.ENFIELD=''C'' and b.[VALUES]=''值'')')
JRQ 2008-07-27
  • 打赏
  • 举报
回复
to 5楼 fcuandy :

多谢您大力帮忙。

您的动态SQL、exec(@sql1+@sql2+@sql3)、select rtrim()。

三个问题搞完后,果然搞定!

非常感谢!


to 10楼 npkaida :

多谢!按照您提供的方法,再加上rtrim()函数,问题搞定!

------

非常感谢楼上的各位提供的动态SQL方法,今天一天学习了不少东西。

多谢各位了!
-狙击手- 2008-07-27
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 wgzaaa 的回复:]
估计是做广告的被和尚抓住了
[/Quote]


大力金刚掌凶得很
fcuandy 2008-07-27
  • 打赏
  • 举报
回复
union all
需要前后进行联合的行集
1,列数一样
2,对应位置的列类型一致或可隐式转换。


比如
select 1 as id
union all
select 'x'
就会报错,第一行的select 1 as id确定的产生的结果集中 id为int
而第二个行集,产生的是varchar,它尝试将'x'转换为int所以报错

select rtrim(1) as id
union all
select 'x'
这样就可以。
JRQ 2008-07-27
  • 打赏
  • 举报
回复
to 楼上:
:(
那2000的写法该如何呢?
hery2002 2008-07-27
  • 打赏
  • 举报
回复
22楼的写法是sql server 2005的 :)
JRQ 2008-07-27
  • 打赏
  • 举报
回复
[Quote=引用 22 楼 npkaida 的回复:]
declare @s varchar(8000)
set @s=';with t as (select *, (select case ENFIELD'
select @s=@s + ' when '''+ENFIELD+''' then '+ENFIELD from t1

set @s=@s+' end from t2) [values] from t1)'+
' select * from t where (ENFIELD=''A'' and [VALUES]=''值1'') or (ENFIELD=''C'' and [VALUES]=''值3'')'

exec(@s)

[/Quote]

to npkaida :

运行提示信息:---

';' 附近有语法错误。
zhiguo2008 2008-07-27
  • 打赏
  • 举报
回复
[Quote=引用 22 楼 npkaida 的回复:]
SQL code
if object_id('t1') is not null
drop table t1
go
create table t1(ENFIELD char(1), CHNAME varchar(10))
insert into t1
select 'A', '序号1' union all
select 'B', '序号2' union all
select 'C', '序号3' union all
select 'D', '序号4' union all
select 'E', '序号5'

if object_id('t2') is not null
drop table t2
go
create table t2(A varchar(10), B varchar(10), C varcha…
[/Quote]
rhq12345 2008-07-27
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 tianhuo_soft 的回复:]
SQL code/*
标题:普通行列转换(version 2.0)
作者:爱新觉罗.毓华
时间:2008-03-09
地点:广东深圳
说明:普通行列转换(version 1.0)仅针对sql server 2000提供静态和动态写法,version 2.0增加sql server 2005的有关写法。

问题:假设有张学生成绩表(tb)如下:
姓名 课程 分数
张三 语文 74
张三 数学 83
张三 物理 93
李四 语文 74
李四 数学 84
李四 物理 94
想变成(得到如下结果):
姓名 语文 数学 物理…
[/Quote]
fcuandy 2008-07-27
  • 打赏
  • 举报
回复
[Quote=引用 21 楼 jrq 的回复:]
to fcuandy :

您好!

我已经正常查询出所需的结果了,如下:
-------
ENFIELD CHNAME VALUES
A 序号1 值1
B 序号2 值2
C 序号3 值3
D 序号4 值4
E 序号5 值5
... ... ...


在您写的SQL的基础上,我想做查询利用--想加上复杂的查询条件, 这样的SQL能否做到??

如,我想…
[/Quote]

可以,把条件加在相应正确的位置就行。
JRQ 2008-07-27
  • 打赏
  • 举报
回复
declare @s varchar(8000)
set @s=';with t as (select *, (select case ENFIELD'
select @s=@s + ' when '''+ENFIELD+''' then '+ENFIELD from t1

set @s=@s+' end from t2) [values] from t1)'+
' select * from t where (ENFIELD=''A'' and [VALUES]=''值1'') or (ENFIELD=''C'' and [VALUES]=''值3'')'

exec(@s)

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

运行提示信息: ';' 附近有语法错误。

请问,在SQL2000下,应该如何拼写动态SQL?
npkaida 2008-07-27
  • 打赏
  • 举报
回复

if object_id('t1') is not null
drop table t1
go
create table t1(ENFIELD char(1), CHNAME varchar(10))
insert into t1
select 'A', '序号1' union all
select 'B', '序号2' union all
select 'C', '序号3' union all
select 'D', '序号4' union all
select 'E', '序号5'

if object_id('t2') is not null
drop table t2
go
create table t2(A varchar(10), B varchar(10), C varchar(10), D varchar(10), E varchar(10))
insert into t2
select '值1', '值2', '值3', '值4', '值5'

declare @s varchar(8000)
set @s=';with t as (select *, (select case ENFIELD'
select @s=@s + ' when '''+ENFIELD+''' then '+ENFIELD from t1

set @s=@s+' end from t2) [values] from t1)'+
' select * from t where (ENFIELD=''A'' and [VALUES]=''值1'') or (ENFIELD=''C'' and [VALUES]=''值3'')'

exec(@s)

ChinaJiaBing 2008-07-27
  • 打赏
  • 举报
回复

if object_id('表1')is not null
drop table 表1
if object_id('表2') is not null
drop table 表2
if object_id('c') is not null
drop table c
go

create table 表1
( ENFIELD nvarchar(2),
CHNAME nvarchar(6)
)
insert into 表1 select 'A','序号1'
union all select 'B','序号2'
union all select 'C','序号3'
union all select 'D','序号4'
union all select 'E','序号5'
go
create table 表2
( A nvarchar(4),
B nvarchar(4),
C nvarchar(4),
D nvarchar(4),
E nvarchar(4)
)
insert into 表2 select '值1' ,'值2', '值3', '值4', '值5'
go

select A AS VALUSE,ENFIELD INTO c FROM
(select A ,'A' AS ENFIELD from 表2
union all
select B ,'B' from 表2
union all
select C ,'C' from 表2
union all
select D,'D' from 表2
union all
select E ,'E'from 表2) b

select a.ENFIELD,a.CHNAME,c.VALUSE FROM 表1 a inner join c on a.ENFIELD=c.ENFIELD
------
A 序号1 值1
B 序号2 值2
C 序号3 值3
D 序号4 值4
E 序号5 值5
leer168 2008-07-27
  • 打赏
  • 举报
回复
看不懂 太难了
帮顶
JRQ 2008-07-27
  • 打赏
  • 举报
回复
to wangjianming45 :

你这个是2005的吧?我的数据库是2000的。 :(
JRQ 2008-07-27
  • 打赏
  • 举报
回复
to fcuandy :

您好!

我已经正常查询出所需的结果了,如下:
-------
ENFIELD CHNAME VALUES
A 序号1 值1
B 序号2 值2
C 序号3 值3
D 序号4 值4
E 序号5 值5
... ... ...


在您写的SQL的基础上,我想做查询利用--想加上复杂的查询条件, 这样的SQL能否做到??

如,我想做类似的查询,加上查询条件:
-----
... where (ENFIELD='A' and VALUES='值1') or (ENFIELD='C' and VALUES='值3')


根据查询条件,得到这样的结果:
------
ENFIELD CHNAME VALUES
A 序号1 值1
C 序号3 值3



-----我能否做到?? 该如何拼写SQL呢? 谢谢。


wangjianming45 2008-07-27
  • 打赏
  • 举报
回复
USE TEST
GO

CREATE TABLE dbo.T1
(
ID INT IDENTITY(1,1) NOT NULL
,ENFIELD NVARCHAR(10) NULL
,CHNAME NVARCHAR(10) NULL
,CONSTRAINT PK_T1 PRIMARY KEY (ID ASC)
)
INSERT INTO dbo.T1
SELECT 'A','序号1' UNION ALL
SELECT 'B','序号2' UNION ALL
SELECT 'C','序号3' UNION ALL
SELECT 'D','序号4' UNION ALL
SELECT 'E','序号5'
GO
create table dbo.T2
(
ID INT IDENTITY(1,1) NOT NULL
,A NVARCHAR(10) NULL
,B NVARCHAR(10) NULL
,C NVARCHAR(10) NULL
,D NVARCHAR(10) NULL
,E NVARCHAR(10) NULL
,CONSTRAINT PK_T2 PRIMARY KEY (ID ASC)
)
INSERT INTO dbo.T2
SELECT '值1','值2', '值3', '值4', '值5'
GO
SELECT A.ENFIELD,A.CHNAME,B.VALU
FROM dbo.T1 AS A
INNER JOIN (
SELECT Turn,VALU
FROM
(
SELECT A,B,C,D,E FROM dbo.T2
) AS P
UNPIVOT
(
VALU FOR Turn IN (A,B,C,D,E)
)AS Temp) AS B
ON A.ENFIELD=B.Turn


hery2002 2008-07-27
  • 打赏
  • 举报
回复
你在他动态的基础上加上你的条件就可以了啥,
5楼那个动态SQL
适合2000
JRQ 2008-07-26
  • 打赏
  • 举报
回复
我用的是2000

发现用union all时候

如果字段类型不一致的时候,会报错:

---“将 varchar 值 转换为数据类型为 int 的列时发生语法错误”
加载更多回复(15)

34,575

社区成员

发帖
与我相关
我的任务
社区描述
MS-SQL Server相关内容讨论专区
社区管理员
  • 基础类社区
  • 二月十六
  • 卖水果的net
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧