求SQL语句,如何将姓名相同的不同数据显示成一行(50分)

  • 主题发起人 主题发起人 sanqou
  • 开始时间 开始时间
S

sanqou

Unregistered / Unconfirmed
GUEST, unregistred user!
如:原表记录数据
Name PhoneNo   HomeNo    OfficeNo
张三 1390826858
张三       85698545
张三              88985831

现想显示成一行:
Name PhoneNo   HomeNo    OfficeNo
张三 1390826858 85698545  88985831
 
交叉数据报表
有时候需要旋转结果以便在水平方向显示列,而在垂直方向显示行。这就是所谓的创建 PivotTable®、创建交叉数据报表或旋转数据。

假定有一个表 Pivot,其中每季度占一行。对 Pivot 的 SELECT 操作在垂直方向上列出这些季度:

Year Quarter Amount
---- ------- ------
1990 1 1.1
1990 2 1.2
1990 3 1.3
1990 4 1.4
1991 1 2.1
1991 2 2.2
1991 3 2.3
1991 4 2.4

生成报表的表必须是这样的,其中每年占一行,每个季度的数值显示在一个单独的列中,如:

Year
Q1
Q2
Q3
Q4

1990
1.1
1.2
1.3
1.4

1991
2.1
2.2
2.3
2.4



下面的语句用于创建 Pivot 表并在其中填入第一个表中的数据:

USE Northwind
GO

CREATE TABLE Pivot
( Year SMALLINT,
Quarter TINYINT,
Amount DECIMAL(2,1) )
GO
INSERT INTO Pivot VALUES (1990, 1, 1.1)
INSERT INTO Pivot VALUES (1990, 2, 1.2)
INSERT INTO Pivot VALUES (1990, 3, 1.3)
INSERT INTO Pivot VALUES (1990, 4, 1.4)
INSERT INTO Pivot VALUES (1991, 1, 2.1)
INSERT INTO Pivot VALUES (1991, 2, 2.2)
INSERT INTO Pivot VALUES (1991, 3, 2.3)
INSERT INTO Pivot VALUES (1991, 4, 2.4)
GO

下面是用于创建旋转结果的 SELECT 语句:

SELECT Year,
SUM(CASE Quarter WHEN 1 THEN Amount ELSE 0 END) AS Q1,
SUM(CASE Quarter WHEN 2 THEN Amount ELSE 0 END) AS Q2,
SUM(CASE Quarter WHEN 3 THEN Amount ELSE 0 END) AS Q3,
SUM(CASE Quarter WHEN 4 THEN Amount ELSE 0 END) AS Q4
FROM Northwind.dbo.Pivot
GROUP BY Year
GO

该 SELECT 语句还处理其中每个季度占多行的表。GROUP BY 语句将 Pivot 中一年的所有行合并成一行输出。当执行分组操作时,SUM 聚合中的 CASE 函数的应用方式是这样的:将每季度的 Amount 值添加到结果集的适当列中,在其它季度的结果集列中添加 0。

如果该 SELECT 语句的结果用作电子表格的输入,那么电子表格将很容易计算每年的合计。当从应用程序使用 SELECT 时,可能更易于增强 SELECT 语句来计算每年的合计。例如:

SELECT P1.*, (P1.Q1 + P1.Q2 + P1.Q3 + P1.Q4) AS YearTotal
FROM (SELECT Year,
SUM(CASE P.Quarter WHEN 1 THEN P.Amount ELSE 0 END) AS Q1,
SUM(CASE P.Quarter WHEN 2 THEN P.Amount ELSE 0 END) AS Q2,
SUM(CASE P.Quarter WHEN 3 THEN P.Amount ELSE 0 END) AS Q3,
SUM(CASE P.Quarter WHEN 4 THEN P.Amount ELSE 0 END) AS Q4
FROM Pivot AS P
GROUP BY P.Year) AS P1
GO

带有 CUBE 的 GROUP BY 和带有 ROLLUP 的 GROUP BY 都计算与本例显示相同的信息种类,但格式稍有不同。
 
Select T1.Name, T1.PhoneNo, T2.HomeNo, T3.OfficeNo
From 原表 T1
Inner Join 原表 T2 On T1.Name=T2.Name
Inner Join 原表 T3 On T1.Name=T3.Name
Where (T1.PhoneNo IS NOT NULL)
AND (T2.HomeNo IS NOT NULL)
AND (T3.OfficeNo IS NOT NULL)
 
转:

問個行合併的問題哈!!現在有如下形式的數據:
BuyId clientName tel
24 xu 123,124,111
24 zhang 1110 135 111
24 张山 010-121212
經過合併后成:
BuyId clientName tel
24 xu zhang 张山 123,124,111 1110 135 111 010-121212

試問要實現上過程,該如何寫sql語句呢?
(數據並不一定是上面確定的數據)


问题点数:20、回复次数:2

1楼 zhaoanle (zhao) 回复于 2006-02-09 11:28:50 得分 0
create function f_c(@buyid varchar(10))
returns varchar(8000)
as
begin
declare @char varchar(8000)
set @char=''
select @char=@char+clientname+' ' from tb where buyid=@buyid
return left(@char,len(@char)-1)
end

go

create function f_t(@buyid varchar(10))
returns varchar(8000)
as
begin
declare @char varchar(8000)
set @char=''
select @char=@char+tel+' ' from tb where buyid=@buyid
return left(@char,len(@char)-1)
end

go

select distinct BuyId,dbo.f_c(BuyId),dbo.f_t(BuyId) from tb

Top
2楼 samfeng_2003 (凤翼天翔) 回复于 2006-02-09 11:28:58 得分 0
create table t
(BuyId int,clientName varchar(20),tel varchar(50))
insert t
select 24,'xu','123,124,111' union all
select 24,'zhang','1110 135 111' union all
select 24,'张山','010-121212'
go
create function f_he(@id int,@col int)
returns varchar(100)
as
begin
declare @sql varchar(100)
set @sql=''
if @col=0
select @sql=@sql+' '+tel from t where BuyId=@id
else
select @sql=@sql+' '+clientName from t where BuyId=@id
return(stuff(@sql,1,1,''))
end
go

select BuyId,dbo.f_he(BuyId,1) as clientName,dbo.f_he(BuyId,0) as tel from t group by BuyId

drop table t
drop function f_he
 
1、我用的是access做数据库
2、可能不是交叉表的问题
3、上面的好象都调试不通
 
试试
select name ,Max(PhoneNo) as PhoneNo,Max(HomeNo) as HomeNo,Max(OfficeNo) as OfficeNo from 表名 group by name
 
假设原表名为set
select distinct set1.name,set2.phoneno,set3.homeno,set4.officeno
from
(select distinct name from set where name='张三') as set1,
(select distinct phoneno from set where name='张三' and phoneno>1) as set2,
(select distinct homeno from set where name='张三' and homeno>1) as set3,
(select distinct officeno from set where name='张三' and officeno>1) as set4
 
表名table1

select distinct A.Name, B.PhoneNO, C.HomeNO, D.OfficeNO
from Table1 as A
left join Table1 as B on A.Name=B.Name and B.PhoneNO is not NULL
left join Table1 as C on A.Name=C.Name and C.HomeNO is not NULL
left join Table1 as D on A.Name=D.Name and D.OfficeNO is not NULL
 
如果使用DISTINCT语句
那么取的记录一定是重复记录当中最顶部的记录!
这是一个问题,学习^^^^^^^^^^^^^^^^^^^^^^^^
 
上面的一个也调试不通。请大家再帮看看!
 
哈哈,哥们解决了,不过这个也只在指定条件下才能行的通!
select distinct name,(select PhoneNo from table_name where phoneNo <> '') AS phoneNo ,(select HomeNo from table_name where HomeNo <> '')AS HomeNo,(select OfficeNo from table_name where OfficeNo <> '')AS OfficeNo From table_name
 
怎么没有人回复呢,楼主呢,给我加分了
 
楼上的朋友的句子存在子查询返回值限制的问题,而我的句子就不会有这个问题,比如张三的Homeno如果有2个不同的号码的话,就会返回2条记录。
假设原表名为test
select distinct set1.name,set2.phoneno,set3.homeno,set4.officeno
from
(select name from test where name='张三') as set1,
(select phoneno from test where name='张三' and phoneno>1) as set2,
(select homeno from test where name='张三' and homeno>1) as set3,
(select officeno from test where name='张三' and officeno>1) as set4

我已经测试过了,绝对可行,不信你们可以自己试试,要查询其他人的话只需要指定名字就行了。
CREATE TABLE [test] (
[Name] [char] (16) COLLATE Chinese_PRC_CI_AS NOT NULL ,
[PhoneNo] [int] NULL ,
[HomeNo] [int] NULL ,
[OfficeNo] [int] NULL
) ON [PRIMARY]
GO
INSERT INTO [test]([Name], [PhoneNo], [HomeNo], [OfficeNo])
VALUES('张三',11,null,null)
INSERT INTO [test]([Name], [PhoneNo], [HomeNo], [OfficeNo])
VALUES('张三',null,22,null)
INSERT INTO [test]([Name], [PhoneNo], [HomeNo], [OfficeNo])
VALUES('张三',null,null,33)
INSERT INTO [test]([Name], [PhoneNo], [HomeNo], [OfficeNo])
VALUES('张三',null,null,44)
go
 
我已经说过了:"不过这个也只在指定条件下才能行的通!"
 
提问之前,我最初是按下面这个做的:

select name ,Max(PhoneNo) as PhoneNo,Max(HomeNo) as HomeNo,Max(OfficeNo) as OfficeNo from 表名 group by name

怕不好,有重复的电话不好办,因些提问。其他的回答我都不太满意。
注意:用的是access
 
select distinct T.name,P.phoneno,H.homeno,O.officeno
from test T,
(select top 1 from test where name=a.name and PhoneNo is not null) as P,
(select top 1 from test where name=a.name and HomeNo is not null) as H,
(select top 1 from test where name=a.name and OfficeNo is not null) as O,
group by T.name
试一下,如果有问题自己调一下,我想应该可以的
 
楼主是使用什么数据库呀,,我上面在我机器上完全实现了你的功能。
我是在SQLSERVER2000中调试的,字段用的是varchar类型
 
用的是:access
 
select A.NameNo,A.PhoneNo ,B.HomeNo ,C.officeNo from Table1 A
left join Table1 B on A.NameNo= B.NameNo and b.HomeNo<>''
left join Table1 C on A.NameNo=C.NameNo and C.officeNo<>''
where A.PhoneNO<>''
我是在SQL Server2000下
Name PhoneNo   HomeNo    OfficeNo
张三 1390826858 85698545  88985831
 
后退
顶部