一个复杂的SQL查询

xhblzj 2008-04-04 08:24:17
有表A,B,C,D
表间关系:
B表包含字段WOMANID,C表对应B表的每一个WOMANID有1-5条数量不等记录,有WOMANID字段,有CSID,D表有字段CSID和CSNAME,有记录8条
A表是包含JGID和JGNAME,JGID是WONMANID的前5位前7位和前10位,
想要的结果:
A表的所有机构(JGID)下,使用某两种措施(CSNAME)或多种措施的妇女(B表记录)人数.

本人步骤:
一,建立联系,B表通过选取C表的最大MAX(CSID)建立关联,C表与D表CSID对应,
二,通过条件查询得到包含CSNAME1的所有WOMAN记录
三,通过截取WOMANID的5,7,10位与A表建立联系,COUNT后得到A机构下使用措施CSNAME1的妇女人数.结果表S1,

重复一,二,三得到使用CSNAME2的妇女人数结果表S2

四,通过select S1.机构,CSNAME1,CSNAME2
from S1,S2
where (S1.JGID=S2.JGID)的方法想得到A表机构下使用CSNAME1和CSNAME2的人数却提示SQL SERVER内部错误

使用方法2:select s1.jgid,S1.csname1,S2.csname2
from S1 join s2 on s1.jgid=s2.jgid
也不行,同样提示SQL SERVER内部错误

问本人的思路对不对,是不是有其它的查询办法,或其它的函数(我只是简单学习了SQL,好多东西都不会用)能直接得到结果.
附:不能改变数据库结构,只能通过查询得到.
非常感谢各位楼主,多次对本人问题的解答,网上学习真好.先谢谢了!!!!!!!!!!!!!!!
...全文
159 点赞 收藏 15
写回复
15 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
pt1314917 2008-04-05
应该不难。不过楼主说的太复杂了。很模糊。不知道什么意思。。
可以加我QQ:4693718
回复
xhblzj 2008-04-04
我试试吧,我现在不在SQL SERVER那台服务器上,我下午试一下5楼那个能不能出来结果,谢谢5楼!!!
回复
pt1314917 2008-04-04
JGID WOMANID CSID CSNAME
-------------------- ---------------------------------------- -------------------- --------------------------------------------------------------------------------
J0001 J0001W01 C0001 CN0001
J0001 J0001W01 C0002 CN0002
J0001 J0001W01 C0003 CN0003
J0001 J0001W02 C0001 CN0001
J0001 J0001W02 C0003 CN0003


要的结果:
JGID CN0001 CN0002 CN0003
J0001 2 1 3


--只针对这个
declare @sql varchar(8000)
set @sql='select jgid'
select @sql=@sql+','+csname+'=sum(case CSNAME when '''+CSNAME+''' then 1 else 0 end)'
from (select distinct CSNAME from 表名)a
set @sql=@sql+' from 表名 group by jgid'
exec(@sql)
回复
hery2002 2008-04-04
[Quote=引用 6 楼 xhblzj 的回复:]
CN0003下面应该是2,是我打错了
以上查询不能实现,因为聚合函数COUNT不能同时聚合JGID和CSNAME,在实际的库中JGID不只是J0001所以5楼的查询是错的
[/Quote]
为什么不能同时聚合?你的显示都是这样的阿?

JGID CN0001 CN0002 CN0003 CN0004 .....
J0001 2 1 2 0
J0002 0 0 0 0


你的显示是以JGID作为行,CSName作为列显示的阿.
回复
xhblzj 2008-04-04
CN0003下面应该是2,是我打错了
以上查询不能实现,因为聚合函数COUNT不能同时聚合JGID和CSNAME,在实际的库中JGID不只是J0001所以5楼的查询是错的
回复
hery2002 2008-04-04

SELECT JGID,CSNAME,COUNT(1) AS C FROM BCDA_VEW
GROUP BY JGID,CSNAME
/*
JGID CSNAME C
-------------------- -------------------------------------------------------------------------------- -----------
J0001 CN0001 2
J0001 CN0002 1
J0001 CN0003 2

(3 row(s) affected)
*/

如果是上面这个结果的话,行列转换一下就行了。
但是没有想明白 你那个CN003 的 3 是怎么来的?
回复
xhblzj 2008-04-04
首先谢谢各位楼主的支持!!特别谢谢三楼把表写出来!!!
对不起,那几个表太复杂,是软件开发写的,我实在写不出
引用3楼,基本上就是那样
到这一步后:
JGID WOMANID CSID CSNAME
-------------------- ---------------------------------------- -------------------- --------------------------------------------------------------------------------
J0001 J0001W01 C0001 CN0001
J0001 J0001W01 C0002 CN0002
J0001 J0001W01 C0003 CN0003
J0001 J0001W02 C0001 CN0001
J0001 J0001W02 C0003 CN0003


要的结果:
JGID CN0001 CN0002 CN0003
J0001 2 1 3
******
回复
hery2002 2008-04-04
首先,顶1,2,楼,
其次,LZ说的是不是这样的.
可能查询条件需要你自己在添加,因为不知道你所的MAX(CSID)怎么取得,
没有你的数据不好分析.最好是把表,数据,结果贴出来,这样最好.

USE [CSDN]
GO
IF OBJECT_ID(N'A') IS NOT NULL
BEGIN
DROP TABLE A
END
IF OBJECT_ID(N'B') IS NOT NULL
BEGIN
DROP TABLE B
END
IF OBJECT_ID(N'C') IS NOT NULL
BEGIN
DROP TABLE C
END
IF OBJECT_ID(N'D') IS NOT NULL
BEGIN
DROP TABLE D
END
GO
CREATE TABLE A (JGID VARCHAR(20),JGNAME VARCHAR(80))
CREATE TABLE B (WOMANID VARCHAR(40),WOMANNAME VARCHAR(80))
CREATE TABLE C (ID INT IDENTITY(1,1),WOMANID VARCHAR(40),CSID VARCHAR(20),OTHER VARCHAR(80))
CREATE TABLE D (CSID VARCHAR(20),CSNAME NVARCHAR(80))
GO
INSERT INTO A VALUES('J0001','JM0001')
INSERT INTO A VALUES('J0002','JM0002')
INSERT INTO A VALUES('J000001','JM000001')
INSERT INTO A VALUES('J000002','JM000002')
INSERT INTO A VALUES('J000000001','JM000000001')
INSERT INTO A VALUES('J000000002','JM000000002')
GO
INSERT INTO B VALUES('J0001W01','J0001WM01')
INSERT INTO B VALUES('J0001W02','J0001WM02')
INSERT INTO B VALUES('J0000001W01','J0000001WM01')
INSERT INTO B VALUES('J0000001W02','J0000001WM02')
INSERT INTO B VALUES('J0000000001W01','J0000000001WM01')
INSERT INTO B VALUES('J0000000001W02','J0000000001WM02')
GO
INSERT INTO D VALUES('C0001','CN0001')
INSERT INTO D VALUES('C0002','CN0002')
INSERT INTO D VALUES('C0003','CN0003')
INSERT INTO D VALUES('C0004','CN0004')
INSERT INTO D VALUES('C0005','CN0005')
INSERT INTO D VALUES('C0006','CN0006')
INSERT INTO D VALUES('C0007','CN0007')
INSERT INTO D VALUES('C0008','CN0008')
GO
INSERT INTO C VALUES('J0001W01','C0001','')
INSERT INTO C VALUES('J0001W01','C0002','')
INSERT INTO C VALUES('J0001W01','C0003','')
INSERT INTO C VALUES('J0001W02','C0001','')
INSERT INTO C VALUES('J0001W02','C0003','')
INSERT INTO C VALUES('J0000001W01','C0004','')
INSERT INTO C VALUES('J0000000001W02','C0005','')
GO
CREATE VIEW CD_VEW
AS
SELECT C.WOMANID,D.CSID,D.CSNAME FROM C C, D D
WHERE C.CSID = D.CSID
GO
CREATE VIEW BCD_VEW
AS
SELECT B.WOMANID,CD.CSID,CD.CSNAME FROM B B
LEFT JOIN CD_VEW CD ON CD.WOMANID = B.WOMANID
GO
CREATE VIEW BCDA_VEW
AS
SELECT A.JGID,BCD.WOMANID,BCD.CSID,BCD.CSNAME
FROM A A, BCD_VEW BCD
WHERE ( substring(BCD.WOMANID,1,5) = A.JGID )
OR(substring(BCD.WOMANID,1,7) = A.JGID )
OR(substring(BCD.WOMANID,1,7) = A.JGID )
GO
SELECT * FROM BCDA_VEW
/*
JGID WOMANID CSID CSNAME
-------------------- ---------------------------------------- -------------------- --------------------------------------------------------------------------------
J0001 J0001W01 C0001 CN0001
J0001 J0001W01 C0002 CN0002
J0001 J0001W01 C0003 CN0003
J0001 J0001W02 C0001 CN0001
J0001 J0001W02 C0003 CN0003

(5 row(s) affected)
*/

USE [CSDN]
GO
DROP VIEW BCDA_VEW
GO
DROP VIEW BCD_VEW
GO
DROP VIEW CD_VEW
GO
DROP TABLE A
GO
DROP TABLE B
GO
DROP TABLE C
GO
DROP TABLE D
GO
回复
xhblzj 2008-04-04
大家看这个查询:
SELECT TOP 100 PERCENT bansc.dbo.jigou.jigouID AS 编码,
bansc.dbo.jigou.jigou AS 机构名, COUNT(*) AS 现孕
FROM bansc.dbo.jigou RIGHT OUTER JOIN
(SELECT *
FROM (SELECT WIS.T_WomanAccount.WomanID AS 育编,
WIS.T_WomanAccount.Name AS 女名,
WIS.T_WomanAccount.Birthday AS 女出生,
WIS.T_Nation.Name AS 女民族,
WIS.T_WomanAccount.HouseAddress AS 女户籍地,
WIS.T_ContraceptStatus.Name AS 措施,
WIS.T_Contracept.BeginDate AS 措施日期,
WIS.T_WomanAccount.Inhabitation AS 女居住地
FROM WIS.T_WomanAccount LEFT OUTER JOIN
WIS.T_Contracept ON
WIS.T_WomanAccount.WomanID = WIS.T_Contracept.WomanID AND
WIS.T_Contracept.ContraceptID =
(SELECT MAX(ContraceptID) AS ContraceptID
FROM WIS.T_Contracept
WHERE TrashFlag <> 1 AND
WomanID = WIS.T_WomanAccount.WomanID)
LEFT OUTER JOIN
WIS.T_Nation ON
WIS.T_WomanAccount.NationID = WIS.T_Nation.NationID LEFT OUTER
JOIN
WIS.T_ContraceptStatus ON
WIS.T_Contracept.ContraceptStatusID = WIS.T_ContraceptStatus.ContraceptStatusID
WHERE (WIS.T_WomanAccount.TrashFlag <> 1) AND
(WIS.T_Contracept.TrashFlag <> 1 OR
WIS.T_Contracept.TrashFlag IS NULL) AND
(WIS.T_ContraceptStatus.Name = '现孕')) DERIVEDTBL)
DERIVEDTBL ON bansc.dbo.jigou.jigouID = SUBSTRING(DERIVEDTBL.育编, 0, 15) OR
bansc.dbo.jigou.jigouID = SUBSTRING(DERIVEDTBL.育编, 0, 13) OR
bansc.dbo.jigou.jigouID = SUBSTRING(DERIVEDTBL.育编, 0, 10)
GROUP BY bansc.dbo.jigou.jigouID, bansc.dbo.jigou.jigou
ORDER BY bansc.dbo.jigou.jigouID

结果:
编码 机构名 现孕
152801021 西环办 85
152801021001 一居民 8
15280102100101 一居一组 2
15280102100102 一居二组 1
******
只能得到现孕的统计表,如将NAME名字改为放环,就得到放环的表,******

可是使用方法:
通过select S1.机构,CSNAME1,CSNAME2
from S1,S2
where (S1.JGID=S2.JGID)的方法想得到A表机构下使用CSNAME1和CSNAME2的人数却提示SQL SERVER内部错误

使用方法2:select s1.jgid,S1.csname1,S2.csname2
from S1 join s2 on s1.jgid=s2.jgid
也不行,同样提示SQL SERVER内部错误

问本人的思路对不对,是不是有其它的查询办法,或其它的函数(我只是简单学习了SQL,好多东西都不会用)能直接得到结果.
附:不能改变数据库结构,只能通过查询得到.
非常感谢各位楼主,多次对本人问题的解答,我是门外汉,实在不知如何给大家提供更多的信息,见谅!.先谢谢了!!!!!!!!!!!!!!!
回复
hery2002 2008-04-04
[Quote=引用 12 楼 xhblzj 的回复:]
JGID WOMANID CSID CSNAME
-------------------- ---------------------------------------- -------------------- --------------------------------------------------------------------------------
J0001 J0001W01 C0001 CN0001
J0001 J0001W01 …
[/Quote]
整点数据和结果出来,越说我越晕了~
回复
bqb 2008-04-04
[Quote=引用 1 楼 kaikai_kk 的回复:]
LZ怎么不把三个表的字段和数据写出来
还有想要得到的结果

会比你长长的文字描述强!!!
[/Quote]

顶~

提问时最好把环境建好!
回复
kaikai_kk 2008-04-04
LZ怎么不把三个表的字段和数据写出来
还有想要得到的结果

会比你长长的文字描述强!!!
回复
xhblzj 2008-04-04
JGID WOMANID CSID CSNAME
-------------------- ---------------------------------------- -------------------- --------------------------------------------------------------------------------
J0001 J0001W01 C0001 CN0001
J0001 J0001W01 C0002 CN0002
J0001 J0001W01 C0003 CN0003
J0001 J0001W02 C0001 CN0001
J0001 J0001W02 C0003 CN0003

得不到3楼这个结果,包括10,11楼的,因为WOMANID和JGID不是一一对应的,JGID截取了WOMANID的3,5,8位,一个
WOMANID对应三个JGID,一个JGID对应若干个CSID,一个WOMANID通过选取最大函数和CSID是一一对应的,所以以上结果都不对 如果可能的话,放弃使用A表,通过截取WOMANID的3,5,8位能不能得到以3,5,8位为行,以CSNAME为列的统计表
?????
JGID包含3位,5位,8位,是逐级统计CSNAME的使用人数
我对创建表不懂,只会用一些查询,对提供的表情况不准的请大家批评指正
回复
green_wolf 2008-04-04
[Quote=引用 10 楼 green_wolf 的回复:]
a:机构基础信息
B:WOMAN基础信息
C:WOMAN的CS信息
d:CS的代码表
1 得到一个关联结果,每个WOMAN,没次CS都有一行数据
SELECT A.JGID,B.WOMANID,C.CSID,D.CSNAME FROM A,B,C,D
WHERE A.JGID(+)=B.JGID
AND B.WOMANID(+)=C.WOMANID
AND C.CSID=D.CSID
对上面的结果分组统计(上面查询结果标记为T1)
2对上面的结果分组统计,(各机构,不同CS数量统计
SELECT JGID,CSID,COUNT(1) AS CS_NUM,CSID,CSNAME FRO…
[/Quote]
具体思路如上
你根据情况再测试
回复
green_wolf 2008-04-04
a:机构基础信息
B:WOMAN基础信息
C:WOMAN的CS信息
d:CS的代码表
1 得到一个关联结果,每个WOMAN,没次CS都有一行数据
SELECT A.JGID,B.WOMANID,C.CSID,D.CSNAME FROM A,B,C,D
WHERE A.JGID(+)=B.JGID
AND B.WOMANID(+)=C.WOMANID
AND C.CSID=D.CSID
对上面的结果分组统计(上面查询结果标记为T1)
2对上面的结果分组统计,(各机构,不同CS数量统计
SELECT JGID,CSID,COUNT(1) AS CS_NUM,CSID,CSNAME FROM T1 GROUP JGID,CSID
3(上面查询结果标记为T2)
SELECT * FROM T2 WHERE CS_NUM>1
4 (上面查询结果标记为T3)关联CSNAME
SELECT A.*,B.CSNAME FROM T3 A,D B
WHERE A.CSID=B.CSID

5合并结果如下
SELECT A.*,B.CSNAME FROM (SELECT * FROM (SELECT JGID,CSID,COUNT(1) AS CS_NUM,CSID,CSNAME FROM (SELECT A.JGID,B.WOMANID,C.CSID,D.CSNAME FROM A,B,C,D
WHERE A.JGID(+)=B.JGID
AND B.WOMANID(+)=C.WOMANID
AND C.CSID=D.CSID
) GROUP JGID,CSID) WHERE CS_NUM>1) A,D B
WHERE A.CSID=B.CSID
回复
相关推荐
发帖
MS-SQL Server
创建于2007-09-28

3.3w+

社区成员

MS-SQL Server相关内容讨论专区
申请成为版主
帖子事件
创建了帖子
2008-04-04 08:24
社区公告
暂无公告