问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

(高分求助)两个比较难的SQL2000的SQL语句查询问题,非专家莫入!

发布网友 发布时间:2022-04-28 15:38

我来回答

13个回答

热心网友 时间:2022-05-05 08:11

第一题
create table temp_znb_1208_practice(name varchar(10),course varchar(20),score numberic)

insert into temp_znb_1208_practice values('张三','语文',74)
insert into temp_znb_1208_practice values('张三','数学',83)
insert into temp_znb_1208_practice values('张三','物理',93)
insert into temp_znb_1208_practice values('李四','语文',74)
insert into temp_znb_1208_practice values('李四','数学',84)
insert into temp_znb_1208_practice values('王五','语文',74)
insert into temp_znb_1208_practice values('王五','数学',83)
insert into temp_znb_1208_practice values('王五','物理',93)
insert into temp_znb_1208_practice values('王五','历史',100)

select (select count(*) from temp_znb_1208_practice b where b.name=a.name and b.score<=a.score) 序列,* from temp_znb_1208_practice a
1 张三 语文 74.00
2 张三 数学 83.00
3 张三 物理 93.00
1 李四 语文 74.00
2 李四 数学 84.00
1 王五 语文 74.00
2 王五 数学 83.00
3 王五 物理 93.00
4 王五 历史 100.00

第二题先增加一列来做辅助,或者可以另外创建临时表
create table temp_znb_1208_practice_2(name varchar(10),enroll_time varchar(20))

insert into temp_znb_1208_practice_2 values('张三', '2008-01-01')
insert into temp_znb_1208_practice_2 values('张三', '2008-01-20')
insert into temp_znb_1208_practice_2 values('张三', '2008-05-30')
insert into temp_znb_1208_practice_2 values('李四', '2008-04-05')
insert into temp_znb_1208_practice_2 values('李四', '2008-06-08')
--增加列
alter table temp_znb_1208_practice_2 add enroll_times varchar(20)
--更新第一次报到
update temp_znb_1208_practice_2
set enroll_times = '第一次报到' where enroll_time in (select min(b.enroll_time) from temp_znb_1208_practice_2 b
where name=b.name
group by b.name)
--更新第二次报到
update temp_znb_1208_practice_2
set enroll_times='第二次报到' where enroll_time in (select min(b.enroll_time) from temp_znb_1208_practice_2 b
where name=b.name
and enroll_time not in
(select min(b.enroll_time) from temp_znb_1208_practice_2 b where name=b.name group by b.name)
group by b.name)
--更新第三次报到
update temp_znb_1208_practice_2
set enroll_times='第三次报到' where enroll_time in (select min(b.enroll_time) from temp_znb_1208_practice_2 b
where name=b.name
and enroll_time not in
(select min(b.enroll_time) from temp_znb_1208_practice_2 b where name=b.name group by b.name)
and enroll_time not in
(select min(b.enroll_time) from temp_znb_1208_practice_2 b
where name=b.name and enroll_time not in
(select min(b.enroll_time) from temp_znb_1208_practice_2 b where name=b.name group by b.name)
group by b.name)
group by b.name)
--以上3个更新,每个更新的条件和前一个更新有关,去掉前几个时间后求的最小时间就是需要更新的时间。也许还有更好的更新方法,我的方法比较笨
select * from temp_znb_1208_practice_2
--更新结果
张三 2008-01-01 第一次报到
张三 2008-01-20 第二次报到
张三 2008-05-30 第三次报到
李四 2008-04-05 第一次报到
李四 2008-06-08 第二次报到
/*
我想到了更简单的更新方法,比上面一个容易理解,逐行更新,代码如下
--先将标识列enroll_times的值设为null
update temp_znb_1208_practice_2
set enroll_times='null'
--逐行更新
update temp_znb_1208_practice_2
set enroll_times = '第一次报到' where enroll_time in (select min(b.enroll_time) from temp_znb_1208_practice_2 b
where name=b.name and enroll_times='null'
group by b.name)

update temp_znb_1208_practice_2
set enroll_times = '第二次报到' where enroll_time in (select min(b.enroll_time) from temp_znb_1208_practice_2 b
where name=b.name and enroll_times='null'
group by b.name)

update temp_znb_1208_practice_2
set enroll_times = '第三次报到' where enroll_time in (select min(b.enroll_time) from temp_znb_1208_practice_2 b
where name=b.name and enroll_times='null'
group by b.name)
*/

--交叉表转换
select name,
isnull(max(case enroll_times when '第一次报到' then enroll_time end ),'') '第一次报到',
isnull(max(case enroll_times when '第二次报到' then enroll_time end ),'') '第二次报到',
isnull(max(case enroll_times when '第三次报到' then enroll_time end ),'') '第三次报到'
from temp_znb_1208_practice_2
group by name
order by name desc
--最后结果
张三 2008-01-01 2008-01-20 2008-05-30
李四 2008-04-05 2008-06-08

------终于做完了,好累啊,哈哈(码字很辛苦的!)
--另外再送上第二题的oracle做法,用分析函数,一句话就出来了
select name,enroll_time, row_number() over (partition by "NAME" order by enroll_time) '次数' from temp_znb_1208_practice_2;
是不是感觉oracle比sql server强大很多呢?

热心网友 时间:2022-05-05 09:29

很久没有看到有点难度的题目,爽。
上面很多人说得都很有道理,但略显复杂,又是游标又是循环的。
第一题:
wewewe7的方法很好很强大,借用下,加了句order by
select 行号=(select count(*) from 表 b where b.姓名=a.姓名 and b.分数<=a.分数),* from 表 a order by 姓名,分数
第二题:
如法炮制,加一列次数放到临时表temptable,然后就拼接SQL搞定。
select 次数=(select '第'+cast(count(*) as varchar(2))+'次报到' from 表 b where b.姓名=a.姓名 and datediff(day,b.报到日期,a.报到日期)>=0),* into temptable from 表 a
order by 姓名,报到日期

declare @sql varchar(8000)
set @sql = 'select 姓名 '
select @sql = @sql + ' , max(case 次数 when ''' + 次数 + ''' then 报到日期 else 0 end) [' + 次数 + ']'
from (select distinct 次数 from temptable) as a
set @sql = @sql + ' from temptable group by 姓名'
exec(@sql)

热心网友 时间:2022-05-05 11:03

两个都要用到,游标,临时表
第一个:
查询人员表得到数据集合 A

开始循环A
通过A里面的人员信息得到每个人成绩单,且这个成绩单按order by 姓名, 课程, 分数 排序查询数据得到B,同时初始化一个变量P用来保存行号

开始循环B,将信息 行号 姓名 课程 分数加入到临时表,循环的同时行号加1
----
A是外循环,B是内循环,P的初始化在A循环内,每次循环都进行初始化。

第二个:
和第一个一样,两个循环嵌套,子循环中每次都要记录报道时间的次序,并通过这个次序把对应的时间插入到对应的列。
---------
之前需要先得到个人报道次数最多的数值,通过这个数值建立临时表
你可能需要用到
Execute sp_ExecuteSql
例子:
Declare @Sqlchar nvarchar(200)
Set @Sqlchar = 'Select * from AAA'
Execute sp_ExecuteSql @Sqlchar

效果和直接Select * from AAA一样,但这样操作可以让你动态地制定列
---

参考资料:只是思路,采不采用由你

热心网友 时间:2022-05-05 12:55

create table b(姓名 varchar(4),课程 varchar(4),分数 varchar(4))
insert into b values('张三','语文','74');
insert into b values('张三','数学','83');
insert into b values('张三','物理','93');
insert into b values('李四','语文','74');
insert into b values('李四','数学','84');
insert into b values('王五','语文','74');
insert into b values('王五','数学','83');
insert into b values('王五','物理','93');
insert into b values('王五','历史','100')
select 行号=(select count(*) from b where b.姓名=c.姓名 and b.分数<c.分数)+1 ,* from b c
drop table b

create table a(姓名 varchar(4),报道日期 datetime)
insert into a values('张三','2008-01-01');
insert into a values('张三','2008-01-20');
insert into a values('张三','2008-05-30');
insert into a values('李四','2008-04-05');
insert into a values('李四','2008-06-08')
declare @sql varchar(8000)
set @sql='select 姓名'
select @sql = @sql +' , max(case pc when ''' + pc + ''' then 报道日期 else 0 end) [第' + pc+ '次报道]'
from (select distinct (select cast(count(*)+1 as varchar(1)) from a where a.姓名=c.姓名 and a.报道日期<c.报道日期) as pc from a c) as s
set @sql = @sql + ' from (select * ,pc=(select count(*)+1 from a where a.姓名=c.姓名 and a.报道日期<c.报道日期)from a c) as e group by 姓名'
exec(@sql)
drop table a

第2题有点问题,要是日期用VARCHAR则会报错“varchar转换为int语法错误”
用datetime类型的话,会填上1900-01-01 00:00:00.000

热心网友 时间:2022-05-05 15:03

你的第一个问题解决是Select *
select 行号=(select count(*)+1 from 表 b where b.姓名=a.姓名 and b.分数<=a.分数),* from 表 a order by 姓名,分数,行号
第二个问题需要用到游标进行判断,也是先生成一个临时表,最后select临时表就oK了或者你可以利用嵌套查询把所有记录叠加,如(报到日期=第一次查询到的记录+'$'+第二次查询到的记录等等
楼上的回答正确,就是第一个在cout(*)后+1还有order by 姓名,分数改成order by 姓名,分数,行号 这样更好

热心网友 时间:2022-05-05 17:27

----上面murder和gzz_gzz,cool的都没有考虑成绩会出现重复值的情况,
这样得出的结果,李四的数学,和英语的id都会是3
所以用cour(课程)字段排序不会出现重复值,
create table t11 (
nam varchar (20),
cour varchar (20),
score int
)
go
insert into t11 values ('张三' ,'语文', 74 )
insert into t11 values ('张三' ,'英语', 74 )----特意加上有相同分数的
insert into t11 values ('张三', '数学', 83 )
insert into t11 values ('张三', '物理', 93 )
insert into t11 values ('李四', '语文', 74 )
insert into t11 values ('李四', '数学', 84 )
insert into t11 values ('王五', '语文', 74 )
insert into t11 values ('王五', '数学', 83 )
insert into t11 values ('王五', '物理', 93 )
insert into t11 values ('王五', '历史', 100 )
go

select (select count(*) from t11 as t2
where t1.nam=t2.nam and t1.cour<=t2.cour) id,
nam ,cour, score from t11 as t1
order by nam,cour desc

---------------------------------
1 李四 语文 74
2 李四 数学 84
3 李四 英语 84
1 王五 语文 74
2 王五 物理 93
3 王五 数学 83
4 王五 历史 100
1 张三 语文 74
2 张三 物理 93
3 张三 数学 83
----------------------------------
--第二个问题是这样:
create table t2(name varchar(10),e_time varchar(20))
insert into t2 values('张三', '2008-01-01')
insert into t2 values('张三', '2008-01-20')
insert into t2 values('张三', '2008-05-30')
insert into t2 values('张三', '2008-06-30')----多插入几行
insert into t2 values('张三', '2008-07-30')
insert into t2 values('李四', '2008-04-05')
insert into t2 values('李四', '2008-06-08')

alter table t2 add keycol int

update t2
set keycol=(select count(*) from t2 as t where t.name=t2.name
and t.e_time<=t2.e_time)
from t2 as t2;
----group by 的话要用聚合函数,所以用max不会影响结果
select * from t2
select name,max(case when keycol=1 then e_time end) as '第一次',
max(case when keycol=2 then e_time end) as '第二次',
max(case when keycol=3 then e_time end) as '第三次',
max(case when keycol=4 then e_time end) as '第四次',
max(case when keycol=5 then e_time end) as '第五次'
from t2
group by name

---结果:
name 第一次 第二次 第三次 第四次 第五次
李四 2008-04-05 2008-06-08 NULL NULL NULL
张三 2008-01-01 2008-01-20 2008-05-30 2008-06-30 2008-07-30

热心网友 时间:2022-05-05 20:09

你的题我会做。但都不太简单。
怕费事做完了没有分。
想要答案的话HI我就行了。
-------------
create table t1 (
nam varchar (20),
cour varchar (20),
score int
)
go
insert into t1 values ('张三' ,'语文', 74 )
insert into t1 values ('张三', '数学', 83 )
insert into t1 values ('张三', '物理', 93 )
insert into t1 values ('李四', '语文', 74 )
insert into t1 values ('李四', '数学', 84 )
insert into t1 values ('王五', '语文', 74 )
insert into t1 values ('王五', '数学', 83 )
insert into t1 values ('王五', '物理', 93 )
insert into t1 values ('王五', '历史', 100 )
go
SELECT (SELECT COUNT(*) FROM t1 B
WHERE B.nam = A.nam AND B.score <= A.score) as ord,*
FROM t1 A
ORDER BY A.nam, A.score

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

create table t2(name varchar(10),enroll_time varchar(20))
go
insert into t2 values('张三', '2008-01-01')
insert into t2 values('张三', '2008-01-20')
insert into t2 values('张三', '2008-05-30')
insert into t2 values('李四', '2008-04-05')
insert into t2 values('李四', '2008-06-08')
go
create FUNCTION f_str(@id varchar(20))
RETURNS varchar(8000)
AS
BEGIN
DECLARE @r varchar(8000)
SET @r = ''
SELECT @r = @r + ',' + enroll_time FROM t2 WHERE name=@id
RETURN STUFF(@r, 1, 1, '')

END

GO
-- 调用函数

SELECt name, enter_time= dbo.f_str(name) FROM t2 GROUP BY name

drop table t2
drop function dbo.f_str

--PS:这确实是两道很经典的题目
--我不怕垫底,再说明一下根本就没有必要考虑分数重复的情况因实际的设计
--表的时修一定会用一个唯一不重复的主键ID的所以只要把B.score <= A.score
--换成a.id<=b.id就行了。不知这样说对不对呢。

热心网友 时间:2022-05-05 23:07

第一个写好了 :
select 行号=(select count(1) from 表 b where b.姓名=a.姓名 and b.分数<=a.分数),* from 表 a

第二个有点难,不太会,希望对你有帮助

热心网友 时间:2022-05-06 02:21

高度关注,看看谁能给出第二个答案,我好收藏。。。

貌似答案已经出来了哦。不错不错。

热心网友 时间:2022-05-06 05:53

第一题用row_number分析函数做吧,第二题纵表转横表根据时间来判断。

热心网友 时间:2022-05-06 09:41

写这个数据库脚本很简单,就怕做了不给分哦。。

热心网友 时间:2022-05-06 13:45

先顶一下.中午再帮你把代码写出来...

热心网友 时间:2022-05-06 18:07

NB.
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
ef英语哪个好 EF英孚英语培训怎么样? 英孚英语好不好 EF英孚教育到底好不好 大佬们,麦芒7和荣耀10那个值得入手?2500以下的机子还有啥好推荐的么... 介绍几款2500元以前的手机 像素一定要高 其他的不做要求 近期想入手一部安卓手机,价格2200到2500左右…买HTC desire Z还是 三星... 笔记本忘记开机密码怎么办急死了 笔记本电脑屏幕开机锁忘记密码 怎么办?急死了 华硕笔记本电脑开机密码忘记了怎样找回?系统是Windows 7旗舰版... Oracle中使用to_number()函数,里面有文字怎么解决 这句select row_number() over (order by ProductID asc) as RowIndex... oracle里面更新操作能带有四则运算吗 Oracle数据库下 distinct 与row_number() over的用法 oracle 多字段查询数据排重,除了row_number()over(partition by )还能... 如何使用连接表替代oracle 的lag() 函数 oracle中的over函数怎么用的,什么意思 Oracle row_number() over()解析函数高效实现分页 oracle 分析函数rank()over()使用,与group by的区别 SQL lag() over()函数用法什么用? ORACLE的CASE函数和RANK函数套用,这是查询代码中的一部分,代码没问题... oracle7中如何分组排序(就像使用rank函数的功能一样的结果) 梦到家中被水淹了,啥意思 昨晚梦到我家了,我回家前面别人家的房子还好好的,可走到我家那路口,发现没路走了,就我一家被水淹了! 梦到去上学别人家房子被水淹没 梦见别的地方房子被洪水冲塌,但是家里有一个生病的老人,这代表什么意 ... 为什么香蕉放冰箱里会变黑? 如何防止香蕉变黑 香蕉的芯变黑还能吃吗? 香蕉里面有点黑了还能吃吗? 我要用oracle根据我截取到的年龄分组,查询显示其它字段,但是不用max... 使用oracle求出制定日期(timestamp或date类型)的后三天日期,请问用哪 ... 股票里多出标准券是什么意思 股票里的标准券怎么取出 有没有关于excel最基础使用(如使用函数、填充柄、换行时自动编号等)的word版本,最好有截图的 装修必须知道的软装搭配知识都有什么? 美式软装搭配要注意什么?搭配技巧有哪些? 黄色的墙面,软装该如何搭配? 现代简约风格软装如何搭配 软装的色彩如何搭配比较好呢? 红木装修软装怎么搭配? 标准券买了要几天能卖 精装修房如何搭配软装 软装色彩搭配六大技巧 办公室软装搭配技巧有哪些? 软装搭配色彩搭配比例的几个原则 软装设计中需要注意的色彩搭配禁忌和技巧有哪些 在日本电视里可以播放huang篇吗 日本人对性是什么态度 谁要是有好看的日本后宫发一下