求SQL语句:查询结果列转行(多表查询,并分组)

liwei47760257 2008-10-27 12:52:43
多行记录和平为一行SQL(多表查询)

问题描述:
表:TAB_INFORMATION_KEYWORD (以下简称t1)
含有3个字段:
AUTOID INFORMATION_ID TAB_KEYWORD_DICTIONARY_ID
1 2 1
2 4 1
3 6 2
表: TAB_KEYWORD_DICTIONARY (以下简称t2)
含有3个字段
AUTOID KEYWORD KEYWORD_EN
1 中国 zg
2 欢迎 hy

所求结果: 这个查询结果关联到这2个表 ,所需要的结果如下
( t2) KEYWORD_EN (t1) INFORMATION_ID
zg 2,4
hy 6

问题就把理应多行记录合并为1行,并分组.(2个表查询)
希望大大们帮下我,我整了1天了. 在线等! 感激不尽
...全文
636 26 打赏 收藏 转发到动态 举报
写回复
用AI写文章
26 条回复
切换为时间正序
请发表友善的回复…
发表回复
zjcxc 元老 2008-10-27
  • 打赏
  • 举报
回复
http://topic.csdn.net/u/20081027/12/81f90ff9-d70b-4b16-b3ea-01a07fbf4500.html
-- SQL 2005或之后的版本(之前的版本得写函数啦)
SELECT
t2.KEYWORD_EN,
B.INFORMATION_ID
FROM t2
CROSS APPLY(
SELECT INFORMATION_ID = STUFF(
(
SELECT
  • = ',' + RTRIM
  • (INFORMATION_ID)
    FROM t1
    WHERE t2.AUTOID = t1.TAB_KEYWORD_DICTIONARY_ID
    FOR XML PATH(''), TYPE
    ).value('/', 'varchar(8000)'),
    1, 1, '')
    )B
dawugui 2008-10-27
  • 打赏
  • 举报
回复
--2005中的方法.
create table [t1] (AUTOID int,INFORMATION_ID int,TAB_KEYWORD_DICTIONARY_ID int)
insert into [t1]
select 1,2,1 union all
select 2,4,1 union all
select 3,6,2
create table [t2] (AUTOID int,KEYWORD varchar(4),KEYWORD_EN varchar(2))
insert into [t2]
select 1,'中国','zg' union all
select 2,'欢迎','hy'
go

select t2.KEYWORD_EN , n.INFORMATION_ID from t2,
(select TAB_KEYWORD_DICTIONARY_ID, [INFORMATION_ID]=stuff((select ','+cast(INFORMATION_ID as varchar) from t1 t where TAB_KEYWORD_DICTIONARY_ID=t1.TAB_KEYWORD_DICTIONARY_ID for xml path('')), 1, 1, '') from t1 group by TAB_KEYWORD_DICTIONARY_ID) n
where t2.autoid = n.TAB_KEYWORD_DICTIONARY_ID

drop table t1,t2
/*
KEYWORD_EN INFORMATION_ID
---------- --------------
zg 2,4
hy 6

(2 行受影响)
*/

zjcxc 元老 2008-10-27
  • 打赏
  • 举报
回复
另一个帖里面不是有答案了吗?
dawugui 2008-10-27
  • 打赏
  • 举报
回复
--2000中用函数的方法.

create table [t1] (AUTOID int,INFORMATION_ID int,TAB_KEYWORD_DICTIONARY_ID int)
insert into [t1]
select 1,2,1 union all
select 2,4,1 union all
select 3,6,2
create table [t2] (AUTOID int,KEYWORD varchar(4),KEYWORD_EN varchar(2))
insert into [t2]
select 1,'中国','zg' union all
select 2,'欢迎','hy'
go

--创建一个合并的函数
create function f_hb(@TAB_KEYWORD_DICTIONARY_ID int)
returns varchar(8000)
as
begin
declare @str varchar(8000)
set @str = ''
select @str = @str + ',' + cast(INFORMATION_ID as varchar) from t1 where TAB_KEYWORD_DICTIONARY_ID = @TAB_KEYWORD_DICTIONARY_ID
set @str = right(@str , len(@str) - 1)
return(@str)
End
go

--调用自定义函数得到结果:
select t2.KEYWORD_EN , n.INFORMATION_ID from t2,
(select distinct TAB_KEYWORD_DICTIONARY_ID ,dbo.f_hb(TAB_KEYWORD_DICTIONARY_ID ) as INFORMATION_ID from t1) n
where t2.AUTOID = n.TAB_KEYWORD_DICTIONARY_ID

drop table t1,t2
drop function dbo.f_hb

/*
KEYWORD_EN INFORMATION_ID
---------- --------------
zg 2,4
hy 6

(所影响的行数为 2 行)

*/
zhouzhijian888 2008-10-27
  • 打赏
  • 举报
回复
你有没有qq
-狙击手- 2008-10-27
  • 打赏
  • 举报
回复
t1 和t3通过什么 关联?

如果 是INFO_ID=INFORMATION_ID

create table [t1] (AUTOID int,INFORMATION_ID int,TAB_KEYWORD_DICTIONARY_ID int)
insert into [t1]
select 1,2,1 union all
select 2,4,1 union all
select 3,6,2 union all
select 4,7,1
create table [t2] (AUTOID int,KEYWORD varchar(4),KEYWORD_EN varchar(2))
insert into [t2]
select 1,'中国','zg' union all
select 2,'欢迎','hy'
create table [t3] (AUTOID int,INFO_ID int,ORDER_ID int,TOP_ORDER_ID int)
insert into t3 values(1 , 4 , 4 , -1 )
insert into t3 values(2 , 6 , 5 , -1 )
insert into t3 values(3 , 7 , 2 , -1 )
insert into t3 values(4 , 2 , 1 , 5 )
go
SELECT
t2.KEYWORD_EN,
B.INFORMATION_ID
FROM t2
CROSS APPLY(
SELECT INFORMATION_ID = STUFF(
(
SELECT
  • = ',' + RTRIM
  • (t1.INFORMATION_ID)
    FROM t1 ,t3
    WHERE t1.INFORMATION_ID = t3. INFO_ID and t2.AUTOID = t1.TAB_KEYWORD_DICTIONARY_ID
    order by t3.TOP_ORDER_ID desc, ORDER_ID desc
    FOR XML PATH(''), TYPE
    ).value('/', 'varchar(8000)'),
    1, 1, '')
    )B


    drop table t1,t2,t3

    /*
    KEYWORD_EN INFORMATION_ID
    ---------- -----------------
    zg 2,4,7
    hy 6

    (2 行受影响)
    */
-狙击手- 2008-10-27
  • 打赏
  • 举报
回复
create table [t1] (AUTOID int,INFORMATION_ID int,TAB_KEYWORD_DICTIONARY_ID int)
insert into [t1]
select 1,2,1 union all
select 2,4,1 union all
select 3,6,2 union all
select 4,7,1
create table [t2] (AUTOID int,KEYWORD varchar(4),KEYWORD_EN varchar(2))
insert into [t2]
select 1,'中国','zg' union all
select 2,'欢迎','hy'
create table [t3] (AUTOID int,INFO_ID int,ORDER_ID int,TOP_ORDER_ID int)
insert into t3 values(1 , 4 , 4 , -1 )
insert into t3 values(2 , 6 , 5 , -1 )
insert into t3 values(3 , 7 , 2 , -1 )
insert into t3 values(4 , 2 , 1 , 5 )
go
SELECT
t2.KEYWORD_EN,
B.INFORMATION_ID
FROM t2
CROSS APPLY(
SELECT INFORMATION_ID = STUFF(
(
SELECT
  • = ',' + RTRIM
  • (t1.INFORMATION_ID)
    FROM t1 ,t3
    WHERE t1.AUTOID = t3.AUTOID and t2.AUTOID = t1.TAB_KEYWORD_DICTIONARY_ID
    order by TOP_ORDER_ID desc, ORDER_ID desc
    FOR XML PATH(''), TYPE
    ).value('/', 'varchar(8000)'),
    1, 1, '')
    )B


    drop table t1,t2,t3

    /*
    KEYWORD_EN INFORMATION_ID
    ---------- -----------------
    zg 7,4,2
    hy 6

    (2 行受影响)
    */
-狙击手- 2008-10-27
  • 打赏
  • 举报
回复
[Quote=引用 21 楼 liwei47760257 的回复:]
大家快帮帮15楼啊
[/Quote]


SELECT
t2.KEYWORD_EN,
B.INFORMATION_ID
FROM t2
CROSS APPLY(
SELECT INFORMATION_ID = STUFF(
(
SELECT
  • = ',' + RTRIM
  • (t1.INFORMATION_ID)
    FROM t1 ,t3
    WHERE t1.AUTOID = t3.AUTOID and t2.AUTOID = t1.TAB_KEYWORD_DICTIONARY_ID
    order by TOP_ORDER_ID desc, ORDER_ID desc
    FOR XML PATH(''), TYPE
    ).value('/', 'varchar(8000)'),
    1, 1, '')
    )B

csdyyr 2008-10-27
  • 打赏
  • 举报
回复

CREATE TABLE T1(AUTOID INT, INFORMATION_ID INT, TAB_KEYWORD_DICTIONARY_ID INT)
INSERT T1
SELECT 1, 2, 1 UNION ALL
SELECT 2, 4, 1 UNION ALL
SELECT 3, 6, 2 UNION ALL
SELECT 3, 7, 1

CREATE TABLE T2(AUTOID INT, KEYWORD NVARCHAR(10), KEYWORD_EN VARCHAR(10))
INSERT T2
SELECT 1, N'中国', 'zg' UNION ALL
SELECT 2, N'欢迎', 'hy' UNION ALL
SELECT 3, N'测试', 'cs'

CREATE TABLE T3(AUTO_ID INT, INFO_ID INT, ORDER_ID INT, TOP_ORDER_ID INT)
INSERT T3
SELECT 1, 4, 4, -1 UNION ALL
SELECT 2, 6, 5, -1 UNION ALL
SELECT 3, 7, 2, -1 UNION ALL
SELECT 4, 2, 1, 5


SELECT INFORMATION_ID,KEYWORD_EN INTO T4
FROM T1 JOIN T2 ON T2.AUTOID=TAB_KEYWORD_DICTIONARY_ID JOIN T3 ON INFO_ID=INFORMATION_ID
ORDER BY KEYWORD_EN,TOP_ORDER_ID desc, ORDER_ID desc
GO

CREATE FUNCTION GetString(@KEYWORD_EN VARCHAR(10))
RETURNS VARCHAR(100)
AS
BEGIN
DECLARE @SQL VARCHAR(100)
SET @SQL=''
SELECT @SQL=@SQL+','+RTRIM(INFORMATION_ID) FROM T4 WHERE KEYWORD_EN=@KEYWORD_EN
RETURN STUFF(@SQL,1,1,'')
END
GO

SELECT KEYWORD_EN,INFORMATION_ID=dbo.GetString(KEYWORD_EN) FROM T4 GROUP BY KEYWORD_EN

DROP TABLE T1
DROP TABLE T2
DROP TABLE T3
DROP TABLE T4
DROP FUNCTION GetString
/*
KEYWORD_EN INFORMATION_ID
---------- ----------------------------------------------------------------------------------------------------
hy 6
zg 2,4,7
*/
zhouzhijian888 2008-10-27
  • 打赏
  • 举报
回复
如果要排序的话 你找个临时表 把排序好后的放进去 再调用
liwei47760257 2008-10-27
  • 打赏
  • 举报
回复
大家快帮帮15楼啊
ningjiaxi 2008-10-27
  • 打赏
  • 举报
回复
if object_id('ff') is not null drop table ff
go
create table ff(id int identity,sid int, pname varchar(20))
insert into ff
select 1,'英语' union all
select 2,'数学' union all
select 1,'日语' union all
select 1,'德语' union all
select 3,'编程'

if object_id('tt') is not null drop table tt
go
create table tt(sid int identity,sname varchar(20))
insert into tt
select '外语' union all
select '理数' union all
select '软件'

--创建函数
create function f_str(@id int)
returns varchar(100)
as
begin
declare @str varchar(20)
set @str=''
select @str=@str+ pname +',' from ff where sid=@id
set @str=left(@str,len(@str)-1)
return (@str)
end
go

--调用函数
select distinct b.sname, dbo.f_str(b.sid) from ff a,tt b where a.sid=b.sid



结果如下:
sname pname
理数 数学
软件 编程
外语 英语,日语,德语
liwei47760257 2008-10-27
  • 打赏
  • 举报
回复
我是楼主, 我起了新贴.地址:

http://topic.csdn.net/u/20081027/12/d43741b4-b18b-4cfb-8fb0-d89a2136fba4.html
15楼 (问题有更新,请看15楼)
liwei47760257 2008-10-27
  • 打赏
  • 举报
回复
我是楼主,大家都看15楼. 问题有更新!
liwei47760257 2008-10-27
  • 打赏
  • 举报
回复
我是楼主,问题有更新,大家都看15楼!!!!!!!!!!
等不到来世 2008-10-27
  • 打赏
  • 举报
回复
SELECT 
t2.KEYWORD_EN,
B.INFORMATION_ID
FROM TAB_KEYWORD_DICTIONARY t2
CROSS APPLY(
SELECT INFORMATION_ID = STUFF(
(
SELECT
  • = ',' + RTRIM
  • (INFORMATION_ID)
    FROM TAB_INFORMATION_KEYWORD t1
    WHERE t2.AUTOID = t1.TAB_KEYWORD_DICTIONARY_ID
    order by TOP_ORDER_ID desc, ORDER_ID desc
    FOR XML PATH(''), TYPE
    ).value('/', 'varchar(8000)'),
    1, 1, '')
    )B
    WHERE B.INFORMATION_ID IS NOT NULL
liwei47760257 2008-10-27
  • 打赏
  • 举报
回复
[Quote=引用 14 楼 liwei47760257 的回复:]
问题描述:
表:TAB_INFORMATION_KEYWORD  (以下简称t1)
  含有3个字段: 
          AUTOID    INFORMATION_ID  TAB_KEYWORD_DICTIONARY_ID
            1          2              1
            2          4              1
            3          6              2
            3          7              1
表: TAB_KEYWORD_DICTIONARY  (以下简称t2)
  含有3个字段:
        AUTOID            KEYWORD          …
[/Quote]
没发好,再整理一次:

问题描述:
表:TAB_INFORMATION_KEYWORD (以下简称t1)
含有3个字段:
AUTOID INFORMATION_ID TAB_KEYWORD_DICTIONARY_ID
1 2 1
2 4 1
3 6 2
3 7 1
表: TAB_KEYWORD_DICTIONARY (以下简称t2)
含有3个字段:
AUTOID KEYWORD KEYWORD_EN
1 中国 zg
2 欢迎 hy
3 测试 cs


表: TAB_INFO_ORDER (以下简称t3)
含有4个字段:
AUTO_ID INFO_ID ORDER_ID TOP_ORDER_ID
1 4 4 -1
2 6 5 -1
3 7 2 -1
4 2 1 5




所求结果: 这个查询结果关联到这3个表 ,所需要的结果如下
( t2) KEYWORD_EN (t1) INFORMATION_ID
zg 2,4 ,7
hy 6



问题就把理应多行记录合并为1行,并分组,并过滤,并排序(3个表查询)


SELECT
t2.KEYWORD_EN,
B.INFORMATION_ID
FROM TAB_KEYWORD_DICTIONARY t2
CROSS APPLY(
SELECT INFORMATION_ID = STUFF(
(
SELECT
  • = ',' + RTRIM
  • (INFORMATION_ID)
    FROM TAB_INFORMATION_KEYWORD t1
    WHERE t2.AUTOID = t1.TAB_KEYWORD_DICTIONARY_ID
    FOR XML PATH(''), TYPE
    ).value('/', 'varchar(8000)'),
    1, 1, '')
    )B
    WHERE B.INFORMATION_ID IS NOT NULL -- 过滤一下就好了吧


    这样已经实现了过滤,合并功能. 但是现在必须加入排序,也就是t3中的INFO_ID 就是上面查询出的INFORMATION_ID 例:2,4 ,7
    但是2,4,7是要经过排序的. 规则为 order by TOP_ORDER_ID desc, ORDER_ID desc
liwei47760257 2008-10-27
  • 打赏
  • 举报
回复
问题描述:
表:TAB_INFORMATION_KEYWORD (以下简称t1)
含有3个字段:
AUTOID INFORMATION_ID TAB_KEYWORD_DICTIONARY_ID
1 2 1
2 4 1
3 6 2
3 7 1
表: TAB_KEYWORD_DICTIONARY (以下简称t2)
含有3个字段:
AUTOID KEYWORD KEYWORD_EN
1 中国 zg
2 欢迎 hy
3 测试 cs


表: TAB_INFO_ORDER (以下简称t3)
含有3个字段:
AUTO_ID INFO_ID ORDER_ID TOP_ORDER_ID
1 4 4 -1
2 6 5 -1
3 7 2 -1
4 2 1 5






所求结果: 这个查询结果关联到这3个表 ,所需要的结果如下
( t2) KEYWORD_EN (t1) INFORMATION_ID
zg 2,4 ,7
hy 6



问题就把理应多行记录合并为1行,并分组,并过滤,并排序(3个表查询)


SELECT
t2.KEYWORD_EN,
B.INFORMATION_ID
FROM TAB_KEYWORD_DICTIONARY t2
CROSS APPLY(
SELECT INFORMATION_ID = STUFF(
(
SELECT
  • = ',' + RTRIM
  • (INFORMATION_ID)
    FROM TAB_INFORMATION_KEYWORD t1
    WHERE t2.AUTOID = t1.TAB_KEYWORD_DICTIONARY_ID
    FOR XML PATH(''), TYPE
    ).value('/', 'varchar(8000)'),
    1, 1, '')
    )B
    WHERE B.INFORMATION_ID IS NOT NULL -- 过滤一下就好了吧



    这样已经实现了过滤,合并功能. 但是现在必须加入排序,也就是t3中的INFO_ID 就是上面查询出的INFORMATION_ID 例:2,4 ,7
    但是2,4,7是要经过排序的. 规则为 order by TOP_ORDER_ID desc, ORDER_ID desc
dawugui 2008-10-27
  • 打赏
  • 举报
回复
是KEYWORD中有'test'吗?

where KEYWORD <> 'test'
dawugui 2008-10-27
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 liwei47760257 的回复:]
多行记录和平为一行SQL(多表查询)

问题描述:
表:TAB_INFORMATION_KEYWORD (以下简称t1)
含有3个字段:
AUTOID INFORMATION_ID TAB_KEYWORD_DICTIONARY_ID
1 2 1
2 4 1
3 6 2
表: TAB_KEYWORD_DICTIONARY (以下简称t2)
含有3个字段
AUTOID KEYWORD KEYWORD_EN
1 中国 zg
2 欢迎 hy
3 测试 cs
所求结果: 这个查询结果关联到这2个表 ,所需要的结果如下
( t2) KEYWORD_EN (t1) INFORMATION_ID
zg 2,4
hy 6

问题就把理应多行记录合并为1行,并分组.(2个表查询)


-- SQL 2005或之后的版本(之前的版本得写函数啦)
SELECT
t2.KEYWORD_EN,
B.INFORMATION_ID
FROM t2
CROSS APPLY(
SELECT INFORMATION_ID = STUFF(
(
SELECT
  • = ',' + RTRIM
  • (INFORMATION_ID)
    FROM t1
    WHERE t2.AUTOID = t1.TAB_KEYWORD_DICTIONARY_ID
    FOR XML PATH(''), TYPE
    ).value('/', 'varchar(8000)'),
    1, 1, '')
    )B

    这样是把所有的都列出来了
    现在t2中含有1条'test'数据
    但是我因为t1中没有此条数据的关系. 所以要过滤掉这条.该怎么弄?
    所求结果: 这个查询结果关联到这2个表 ,所需要的结果如下
    ( t2) KEYWORD_EN (t1) INFORMATION_ID
    zg 2,4
    hy 6


    我是楼主,这是问题补充..[/Quote]
    现在t2中含有1条'test'数据
    但是我因为t1中没有此条数据的关系. 所以要过滤掉这条.该怎么弄?

    把这条(或你不需要的记录)使用where 条件过滤掉就行了.
    但我没看到你的T2表中的数据.
加载更多回复(6)

34,876

社区成员

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

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