一些比较难的sql问题:2(四)
)
insert into t
select cast('2013-05-01' as datetime) as d
union all
select cast('2013-05-10' as datetime)
/*
1.
通过查询计划能看出,SQL Server把下面的查询转化成了:
select * from t where d >= convert(datetime,2013/5/1,0) and d <= convert(datetime,'2013/6/24',0)
也就是查询条件:
d >= convert(datetime,2013/5/1,0) and d <= convert(datetime,'2013/6/24',0)
进一步转化:
d >= '1901-02-07 00:00:00.000' and d <= 2013-06-24 00:00:00.000
这样就能查询出结果集。
*/
select *
from t
where d between convert(datetime,2013/5/1) and convert(datetime,'2013/6/24')
/*
2.
通过查询计划能看出,SQL Server把下面的查询转化成了:
select * from t where d >= convert(datetime,2013/5/1,0) and d <= convert(datetime,2013/6/24,0)
也就是查询条件:
d >= convert(datetime,2013/5/1,0) and d <= convert(datetime,2013/6/24,0)
进一步转化:
d >= '1901-02-07 00:00:00.000' and d <= '1900-01-14 00:00:00.000'
由于SQL Server 把2013/6/24中的斜杠,当成了除号,也就是按除法计算了,
比如:2013/6/24 就等于13,那么由于datetime默认值是默认值: 1900-01-01 00:00:00,
那么加上13后,就是1900-01-14 00:00:00.000,这样后就查不出结果了.
*/
select *
from t
where d between convert(datetime,2013/5/1) and convert(datetime,2013/6/24)
其实就是,
2013/5/1 就是一个除法运算,结果为402。
2013/6/24 做除法运算后,就是13。
由于datetime数据类型的默认值为:'1900-01-01 00:00:00',
所以上面的convert(datetime,2013/5/1)就是'1900-01-01 00:00:00' 再加上402,
就是'1901-02-07 00:00:00.000',
而convert(datetime,2013/6/24)就是是'1900-01-01 00:00:00' 再加上 13,
就是'1900-01-14 00:00:00.000',
所以就会查不出结果来。
所以,上面的2013/5/1 要写成 '2013/5/1',一定要加上引号。
4、求一SQL语句。
[sql]
create table #tab
(
col1 char(10),
col2 char(10),
num int,
[Date] varchar(10))
insert #tab values('AAA','BBB','A',50,'2013-06-10')
insert #tab values('ABB','BGG','B',30,'2013-06-10')
insert #tab values('AAA','BBB','C',80,'2013-06-13')
我的解法:
[sql]
create table tab
(
col1 char(10),
col2 char(10),
item char(10),
num int,
[Date] varchar(10)
)
insert tab values('AAA','BBB','A',50,'2013-06-10')
insert tab values('ABB','BGG','B',30,'2013-06-10')
insert tab values('AAA','BBB','C',80,'2013-06-13')
--动态生成sql语句
declare @start_date varchar(10) = '2013-06-01',
@end_date varchar(10) = '2013-06-30';
declare @date varchar(10),
@sql varchar(max) = '',
@sql1 varchar(8000),
@sql2 varchar(8000);
set @date = @start_date;
set @sql1 = 'select case when rownum = 1 then col1 else '''' end as col1,
case when rownum = 1 then col2 else '''' end as col2,
item'
set @sql2 = 'select col1,col2,item,row_number() over(partition by col1,col2
order by item) as rownum'
while @date <= @end_date
begin
set @sql1 = @sql1 + ',v_' + REPLACE( right(@date,5),'-','') +
' as ''' + CAST(DATEPART(month,@date) as varchar) + '/' +
CAST(DATEPART(day,@date) as varchar) +'''';
set @sql2 = @sql2 + ',SUM(case when date =''' + @date +
''' then num else 0 end) as v_' +
REPLACE( right(@date,5),'-','')
set @date = CONVERT(varchar(10),dateadd(day,1,@date),120)
end
set @sql = @sql1 + ' from (' +
@sql2 + ' from tab
group by col