纵览各大社区、论坛,各大ORM框架火得不行了,如NHibernate、LINQ to SQL、ADO.NET Entity framework等,还有最近市场上出版的一本叫《领域驱动设计与模式实战》,里面也凸显了不少NHibernate在领域驱动设计中的作用与地位,也算是第一本与NHibernate相关的书籍吧!不过就NHibernate而言还是没有官方文档介绍得详细呵呵,园子里
Kiler已经把他翻译成中文版的了,收益一大片仅仅是CET-4的人。不管你是用NHibernate也好,还是用LINQ to SQL也好,用profiler一跟踪,执行的都是SQL语句,所以所SQL是根。特别是对于那些以数据为中心的应用系统,在数据库中实现复杂的存储过程,复杂的报表查询,还是直接SQL来得痛快。
当然
对于那些在基于.NET的中间层应用中,它们实现面向对象的业务模型和商业逻辑的应用,NHibernate是最有用的。不管怎样,NHibernate一定可以帮助你消除或者包装那些针对特定厂商的SQL代码,并且帮你把结果集从表格式的表示形式转换到一系列的对象去(官方文档)。
有点跑题了,不再啰嗦----直接晾出压轴题。
压轴题第一问
1.把表一转换为表二
表一:
![各大软件公司.NET工程师笔试压轴题](http://img.e-com-net.com/image/product/0044b7db14ce4d32b68c57b40e6226f9.png)
表二:
数据库代码如下:
![](http://img.e-com-net.com/image/product/6608db1168bd40d689802616642f351b.gif)
代码
1
DROP table #student
2
CREATE TABLE #student (stdname nvarchar(
10
),stdsubject nvarchar(
10
),result
int
)
3
INSERT INTO #student VALUES (
'
张三
'
,
'
语文
'
,
80
)
4
INSERT INTO #student values (
'
张三
'
,
'
数学
'
,
90
)
5
INSERT INTO #student VALUES (
'
张三
'
,
'
物理
'
,
85
)
6
INSERT INTO #student VALUES (
'
李四
'
,
'
语文
'
,
85
)
7
INSERT INTO #student values (
'
李四
'
,
'
数学
'
,
92
)
8
INSERT INTO #student VALUES (
'
李四
'
,
'
物理
'
,
82
)
9
INSERT INTO #student VALUES (
'
李四
'
,
'
化学
'
,
82
)
10
INSERT INTO #student VALUES (
'
李四
'
,
'
化学
'
,
82
)
11
SELECT
*
FROM #student
可能很多老手们,一看到这题目就有了答案。当然,贴出答案来不是我的目的,我要带着SQL新手们重构到答案。用李建忠老师最爱说的话就是------我不建议一上来就套用模式,而应该从重构到模式。
首先大家会想到分两组
1 select stdname,····,from #student group by stdname
然后······中间该写什么呢?
代码
1
case
stdsubject when
'
化学
'
then Result end
2
case
stdsubject when
'
语文
'
then Result end
3
case
stdsubject when
'
···
'
then Result end
4
case
stdsubject when
'
···
'
then Result end
5
case
stdsubject when
'
···
'
then Result end
表二里面得0是哪里来的呢?
![](http://img.e-com-net.com/image/product/6608db1168bd40d689802616642f351b.gif)
代码
1
isnull(sum(
case
stdsubject when
'
化学
'
then Result end),
0
)
2
isnull(sum(
case
stdsubject when
'
语文
'
then Result end),
0
)
3
isnull(sum(
case
stdsubject when
'
···
'
then Result end),
0
)
4
isnull(sum(
case
stdsubject when
'
···
'
then Result end),
0
)
5
isnull(sum(
case
stdsubject when
'
···
'
then Result end),
0
)
所以得出:
![](http://img.e-com-net.com/image/product/6608db1168bd40d689802616642f351b.gif)
代码
1
select stdname,
2
isnull(sum(
case
stdsubject when
'
化学
'
then Result end),
0
) [化学],
3
isnull(sum(
case
stdsubject when
'
数学
'
then Result end),
0
) [数学],
4
isnull(sum(
case
stdsubject when
'
物理
'
then Result end),
0
) [物理],
5
isnull(sum(
case
stdsubject when
'
语文
'
then Result end),
0
) [语文]
6
from #student
7
group by stdname
然后得出答案:
![](http://img.e-com-net.com/image/product/6608db1168bd40d689802616642f351b.gif)
代码
1
declare @sql varchar(
4000
)
2
set
@sql
=
'
select stdname
'
3
select @sql
=
@sql
+
'
,isnull(sum(case stdsubject when
'''
+
stdsubject
+
'''
then Result end),0) [
'
+
stdsubject
+
'
]
'
4
from (select distinct stdsubject from #student)
as
a
5
select @sql
=
@sql
+
'
from #student group by stdname
'
6
print @sql
7
exec(@sql)
8
压轴题第二问:把表二转化为表一
表一:
![各大软件公司.NET工程师笔试压轴题](http://img.e-com-net.com/image/product/0044b7db14ce4d32b68c57b40e6226f9.png)
表二:
数据库代码如下:
![](http://img.e-com-net.com/image/product/6608db1168bd40d689802616642f351b.gif)
代码
1
DROP table #student2
2
CREATE TABLE #student2 (stdname nvarchar(
10
),化学
int
,数学
int
,物理
int
,语文
int
)
3
INSERT INTO #student2 VALUES (
'
李四
'
,
164
,
92
,
82
,
85
)
4
INSERT INTO #student2 VALUES (
'
张三
'
,
0
,
90
,
85
,
80
)
5
SELECT
*
FROM #student2
看到这题,直接想到:
![](http://img.e-com-net.com/image/product/6608db1168bd40d689802616642f351b.gif)
代码
1
SELECT
'
李四
'
as
stdname,stdname
=
'
化学
'
, 化学
as
result from #student2
where
stdname
=
'
李四
'
2
union all
3
SELECT
'
李四
'
as
stdname,stdname
=
'
数学
'
, 数学
as
result from #student2
where
stdname
=
'
李四
'
4
union all
5
SELECT
'
李四
'
as
stdname,stdname
=
'
物理
'
, 物理
as
result from #student2
where
stdname
=
'
李四
'
6
union all
7
SELECT
'
李四
'
as
stdname,stdname
=
'
语文
'
, 语文
as
result from #student2
where
stdname
=
'
李四
'
8 union all
9
SELECT
'
张三
'
as
stdname,stdname
=
'
化学
'
, 化学
as
result from #student2
where
stdname
=
'
张三
'
10
union all
11
SELECT
'
张三
'
as
stdname,stdname
=
'
数学
'
, 数学
as
result from #student2
where
stdname
=
'
张三
'
12
union all
13
SELECT
'
张三
'
as
stdname,stdname
=
'
物理
'
, 物理
as
result from #student2
where
stdname
=
'
张三
'
14
union all
15
SELECT
'
张三
'
as
stdname,stdname
=
'
语文
'
, 语文
as
result from #student2
where
stdname
=
'
张三
'
重构到:
![](http://img.e-com-net.com/image/product/6608db1168bd40d689802616642f351b.gif)
代码
1
declare @sql2 varchar(
4000
)
2
set
@sql2
=
''
3
SELECT @sql2
=
@sql2
+
4
'
SELECT
'''
+
stdname
+
'''
as stdname,stdname=
''
化学
''
, 化学 as result from #student2 where stdname=
'''
+
stdname
+
'''
5
union all
6
SELECT
'''
+stdname+
'''
as
stdname,stdname
=
''
数学
''
, 数学
as
result from #student2
where
stdname
=
'''
+stdname+
'''
7
union all
8
SELECT
'''
+stdname+
'''
as
stdname,stdname
=
''
物理
''
, 物理
as
result from #student2
where
stdname
=
'''
+stdname+
'''
9
union all
10
SELECT
'''
+stdname+
'''
as
stdname,stdname
=
''
语文
''
, 语文
as
result from #student2
where
stdname
=
'''
+stdname+
'''
union all
'
11
from (SELECT stdname FROM #student2)
as
a
12
SELECT @sql2
=
LEFT(@sql2,LEN(@sql2)
-
10
)
13
PRINT(@sql2)
14
exec(@sql2)
如果要求不能出现 化学 数学 物理 语文 这样的关键字,那么可以这样写:
![](http://img.e-com-net.com/image/product/6608db1168bd40d689802616642f351b.gif)
代码
1
select [name] into #tmpCloumns
2
from tempdb.dbo.syscolumns
3
where
id
=
object_id(
'
tempdb.dbo.#student2
'
)
4
and [name]
<>
'
stdname
'
5
select
*
from #tmpCloumns
6
7
declare @strSql nvarchar(
800
)
8
select @strSql
=
''
9
select @strSql
=
@strSql
+
'
union all
'
+
char
(
10
)
+
char
(
13
)
+
10
'
select [stdname],
'''
+
[name]
+
'''
as [科目],[
'
+
[name]
+
'
]
'
+
char
(
10
)
+
char
(
13
)
+
11
'
from [#student2]
'
+
char
(
10
)
+
char
(
13
)
12
from #tmpCloumns
13
14
select @strSql
=
substring(@strSql,
11
,len(@strSql))
+
'
order by stdname,[科目]
'
15
--
print @strSql
16
exec(@strsql)
这种题目,在各种笔试中出现的概率还是非常大的,大家不用死记。以前有的朋友看着复杂的报表查询,几百行SQL,望而生畏,然后说:"这是哪个SQL超人写的啊!"其实,谁一上来不可能写出那么长的SQL,也是慢慢重构--调试--重构-······