〓〓〓〓求一SQL语句(50分)〓〓〓〓求写正确的查询语句的资料(50分)〓〓〓〓

Sean918 2008-02-04 02:29:34
问题一: (先回答,且最优SQL得50分)
表 Table 数据如下:
==============================
ID | NAME | BEGIN_DATE | STATUS
1 A 2001-01-23 y
2 B 2002-01-11 y
3 B 2003-01-08 y
4 C 2004-01-01 y
5 A 2005-01-07 y
6 D 2006-01-06 y
7 A 2007-01-01 n
8 C 2008-01-05 n
9 C 2002-02-01 n
10 A 2003-04-01 n
。 。 。 。
。 。 。 。
。 。 。 。
n Z 2008-01-08 y
==============================
已知的表信息: ID 为主键 ,对于每组不同的NAME,组中必然有至少一条记录的STATUS='y'

SQL要求:更新表中记录,使得对于每组不同的NAME ,保证组中 BEGIN_DATE 为最小的记录的STATUS='y',其他全部为'n'
==============================



问题二:(50分,不够可加分)

通常按照希望达到的目的写出原始SQL语句后,能够通过运算方法得到最简化的SQL语句
跪求该运算方法,或者涉及简化SQL语句的学习资料。
...全文
113 11 打赏 收藏 转发到动态 举报
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
free1879 2008-02-04
  • 打赏
  • 举报
回复
这主要是经验和知识的积累,我觉得看看关系数据库的理论和一些查询优化的书可以提高吧!
Sean918 2008-02-04
  • 打赏
  • 举报
回复
多谢高人们的帮助!
第一个问题是我考虑错了。

===================

关于第二个问题,其实就是下面的例子:

select dbName from (
select * from @tmpTable
group by dbname,status
) b
where dbName not in(
select dbName from (
select * from @tmpTable
group by dbname,status
) a where status = 'y'
)
对于上面这个SQL ,是最原始的,也就是我怎么想就怎么写出来的SQL

但是它可以写为下面的样子:
select distinct dbname from @tmpTable a
where not exists(select 1 from @tmpTable where a.dbname=dbname and status='y')

=============================================
我想要的,其实就是这样的一种转换方法,能从复杂的SQL 转换到简单的。
因为有人说,可以通过 “与”“或”关系运算得到结果
zf19811031 2008-02-04
  • 打赏
  • 举报
回复
update a
set Status=case when BEGIN_DATE =(select min(BEGIN_DATE) from t GROUP BY NAME)
then 'Y'
else 'N' end
free1879 2008-02-04
  • 打赏
  • 举报
回复
--我觉得这个不错啊
UPDATE t
SET STATUS=(CASE WHEN EXISTS(SELECT 1 FROM #Table WHERE NAME= t.NAME AND BEGIN_DATE<t.BEGIN_DATE) THEN 'n' ELSE 'y' END)
FROM #Table t

/*
ID NAME BEGIN_DATE STATUS
----------- ---------- ----------------------- ----------
1 A 2001-01-23 00:00:00.000 y
2 B 2002-01-11 00:00:00.000 y
3 B 2003-01-08 00:00:00.000 n
4 C 2004-01-01 00:00:00.000 n
5 A 2005-01-07 00:00:00.000 n
6 D 2006-01-06 00:00:00.000 y
7 A 2007-01-01 00:00:00.000 n
8 C 2008-01-05 00:00:00.000 n
9 C 2002-02-01 00:00:00.000 y
10 A 2003-04-01 00:00:00.000 n
11 Z 2008-01-08 00:00:00.000 y

(11 行受影响)
*/
popeye627 2008-02-04
  • 打赏
  • 举报
回复
3楼的好
popeye627 2008-02-04
  • 打赏
  • 举报
回复
方法比较笨,但是可以实现

declare @t table([ID] int primary key,[name] varchar(2),begin_date datetime, status varchar(1))
insert into @t values(1,'A','2001-01-23','y')
insert into @t values(2,'B','2002-01-11','y')
insert into @t values(3,'B','2003-01-08','y')
insert into @t values(4,'C','2004-01-01','y')
insert into @t values(5,'A','2005-01-07','y')
insert into @t values(6,'D','2006-01-06','y')
insert into @t values(7,'A','2007-01-01','n')
insert into @t values(8,'C','2008-01-05','n')
insert into @t values(9,'C','2002-02-01','n')
insert into @t values(10,'A','2003-04-01','n')

select * from @t order by 2,3

update @t
set status='n'

update @t
set status='y'
where id in (
select a.id
from @t a
where not exists(select 1 from @t where name = a.name and begin_date < a.begin_date)
)

select * from @t order by 2,3

----------------------------------------------------------
ID name begin_date status
----------- ---- ----------------------- ------
1 A 2001-01-23 00:00:00.000 y
10 A 2003-04-01 00:00:00.000 n
5 A 2005-01-07 00:00:00.000 y
7 A 2007-01-01 00:00:00.000 n
2 B 2002-01-11 00:00:00.000 y
3 B 2003-01-08 00:00:00.000 y
9 C 2002-02-01 00:00:00.000 n
4 C 2004-01-01 00:00:00.000 y
8 C 2008-01-05 00:00:00.000 n
6 D 2006-01-06 00:00:00.000 y

(10 個資料列受到影響)

(10 個資料列受到影響)

(4 個資料列受到影響)

ID name begin_date status
----------- ---- ----------------------- ------
1 A 2001-01-23 00:00:00.000 y
10 A 2003-04-01 00:00:00.000 n
5 A 2005-01-07 00:00:00.000 n
7 A 2007-01-01 00:00:00.000 n
2 B 2002-01-11 00:00:00.000 y
3 B 2003-01-08 00:00:00.000 n
9 C 2002-02-01 00:00:00.000 y
4 C 2004-01-01 00:00:00.000 n
8 C 2008-01-05 00:00:00.000 n
6 D 2006-01-06 00:00:00.000 y

(10 個資料列受到影響)
free1879 2008-02-04
  • 打赏
  • 举报
回复
CREATE TABLE #Table(
ID int identity(1,1),
NAME varchar(10),
BEGIN_DATE datetime,
STATUS varchar(10));
GO

INSERT #Table(NAME,BEGIN_DATE,STATUS) VALUES('A','2001-01-23','y');
INSERT #Table(NAME,BEGIN_DATE,STATUS) VALUES('B','2002-01-11','y');
INSERT #Table(NAME,BEGIN_DATE,STATUS) VALUES('B','2003-01-08','y');
INSERT #Table(NAME,BEGIN_DATE,STATUS) VALUES('C','2004-01-01','y');
INSERT #Table(NAME,BEGIN_DATE,STATUS) VALUES('A','2005-01-07','y');
INSERT #Table(NAME,BEGIN_DATE,STATUS) VALUES('D','2006-01-06','y');
INSERT #Table(NAME,BEGIN_DATE,STATUS) VALUES('A','2007-01-01','n');
INSERT #Table(NAME,BEGIN_DATE,STATUS) VALUES('C','2008-01-05','n');
INSERT #Table(NAME,BEGIN_DATE,STATUS) VALUES('C','2002-02-01','n');
INSERT #Table(NAME,BEGIN_DATE,STATUS) VALUES('A','2003-04-01','n');
INSERT #Table(NAME,BEGIN_DATE,STATUS) VALUES('Z','2008-01-08','y');
GO

SELECT * FROM #Table
--测试数据
/*
ID NAME BEGIN_DATE STATUS
----------- ---------- ----------------------- ----------
1 A 2001-01-23 00:00:00.000 y
2 B 2002-01-11 00:00:00.000 y
3 B 2003-01-08 00:00:00.000 y
4 C 2004-01-01 00:00:00.000 y
5 A 2005-01-07 00:00:00.000 y
6 D 2006-01-06 00:00:00.000 y
7 A 2007-01-01 00:00:00.000 n
8 C 2008-01-05 00:00:00.000 n
9 C 2002-02-01 00:00:00.000 n
10 A 2003-04-01 00:00:00.000 n
11 Z 2008-01-08 00:00:00.000 y

(11 行受影响)
*/

--更新
UPDATE #Table
SET STATUS='n';
GO

UPDATE #Table
SET STATUS='y'
WHERE BEGIN_DATE IN (SELECT MIN(BEGIN_DATE) FROM #Table GROUP BY NAME)


SELECT * FROM #TABLE

--结果:
/*
ID NAME BEGIN_DATE STATUS
----------- ---------- ----------------------- ----------
1 A 2001-01-23 00:00:00.000 y
2 B 2002-01-11 00:00:00.000 y
3 B 2003-01-08 00:00:00.000 n
4 C 2004-01-01 00:00:00.000 n
5 A 2005-01-07 00:00:00.000 n
6 D 2006-01-06 00:00:00.000 y
7 A 2007-01-01 00:00:00.000 n
8 C 2008-01-05 00:00:00.000 n
9 C 2002-02-01 00:00:00.000 y
10 A 2003-04-01 00:00:00.000 n
11 Z 2008-01-08 00:00:00.000 y

(11 行受影响)
*/
昵称被占用了 2008-02-04
  • 打赏
  • 举报
回复
问题二
不是很明白搂主要什么,一般来说,如果写得出来,写出来的往往是最简化的,没有什么运算
中国风 2008-02-04
  • 打赏
  • 举报
回复
把更新合为一条
update a
set Status=case when BEGIN_DATE =(select min(BEGIN_DATE) from t where Name=a.Name)
then 'Y'
else 'N' end
from
t a
昵称被占用了 2008-02-04
  • 打赏
  • 举报
回复
问题一
update a
set status=case when exists (select 1 from [table] where name=a.name and BEGIN_DATE<a.BEGIN_DATE) then 'n' else 'y' end
from [table] a
中国风 2008-02-04
  • 打赏
  • 举报
回复
select * from t a where exists(select 1 from t where Name=a.Name and Status='Y')--至少有一条


select * from T a where not exists(select 1 from t where Name=a.Name and BEGIN_DATE<a.BEGIN_DATE) --查询最小BEGIN_DATE


update a
set Status='N'
from T a
where exists(select 1 from t where Name=a.Name and BEGIN_DATE<a.BEGIN_DATE)

update a
set Status='Y'
from T a
where not exists(select 1 from t where Name=a.Name and BEGIN_DATE<a.BEGIN_DATE)

34,592

社区成员

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

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