正在學(xué)習(xí)SQL Server 期望收集一些常見(jiàn)的Sql Server 問(wèn)題
Sql Server問(wèn)題摘要
1. 合并若干個(gè)表?
描述:建立一個(gè)新表,其字段結(jié)構(gòu)是其他若干個(gè)表Join以后的結(jié)果。
解決思路:select * into 新表名 from 舊表1名,舊表2名,……
實(shí)例:
--表NewTableName的字段為表titles和titleauthor字段表相加;
---記錄為記錄為select * from titles,titleauthor的記錄
select * into NewTableName from titles,titleauthor
--表NewTableName的字段[title_id,title,au_id]
-- 記錄為select a.title_id,a.title,b.au_id from titles a,titleauthor b where a.title_id=b.title_id
select a.title_id,a.title,b.au_id into NewTableName from titles a,titleauthor b where a.title_id=b.title_id
2. 查詢(xún)N-M條記錄?
描述:要從記錄集中取出中間一段記錄來(lái)(如: 取10條中的第3-8條)
解決思路:
1. 有關(guān)鍵字或確保唯一的候選關(guān)鍵字字段:
方法1:從第n條記錄開(kāi)始取m-n+1條數(shù)據(jù)
方法2:升序取前m條記錄最為a, 再降序從a中取m-n+1條記錄作為b
2. 沒(méi)有上述字段:
增加一個(gè)自增字段生成一個(gè)臨時(shí)表,在從臨時(shí)表中取記錄[Where 自增字段名>n-1]
實(shí)例: --
--取第4到第7條記錄 [對(duì)1方法一]
SELECT top 4 * FROM jobs WHERE job_id not in (SELECT top 3 job_id FROM jobs)
--[方法二]
SELECT top 4 * FROM
(SELECT top 4 * FROM
(SELECT top 7 * FROM jobs ORDER BY job_id ASC) a
ORDER BY job_id DESC
) b
ORDER BY job_id ASC
--取第2到第3條記錄 [對(duì)1方法一]
select IDENTITY(int,1,1) as iid,* into #temptable from discounts select top 2 * from #temptable where iid>=2
3. 按年度季度統(tǒng)計(jì)匯總?
描述: 統(tǒng)計(jì)表employee的各年度各季度的雇傭人數(shù)
解決思路:Group by 和 [函數(shù)datepart()]
實(shí)例:
//季度:quarter
SELECT year(hire_date) 年度,datepart(q,hire_date) 季度,count(emp_id)雇傭人數(shù) FROM employee
GROUP BY year(hire_date),datepart(q,hire_date)
ORDER BY 年度,季度
4. 隨機(jī)取n條記錄?
描述: 從表中隨機(jī)提取n條記錄
解決思路:按照用Guid
實(shí)例:
--從表中隨機(jī)取5條記錄
SELECT top 5 * FROM titles ORDER BY newid()
5. 求出任意時(shí)間所在季度的天數(shù)?
描述: 如題
解決思路:注意閏年
實(shí)例:
declare @t smalldatetime
select @t = ‘2001-4-1‘
select case datepart(quarter,@t)
when 1 then
(case when (year(@t)%4=0 and year(@t)%100<>0) or year(@t)%400=0 then 91 else 90 end)
when 2 then 91
when 3 then 92
when 4 then 92
end
6. 求出任意時(shí)間的季度的第一天?
描述: 如題
解決思路: 如下
實(shí)例:
-- [思路:把日期向前推到季度的第一個(gè)月的當(dāng)前號(hào)
--注意:5月31號(hào)不會(huì)推成4月31號(hào) ,系統(tǒng)自動(dòng)轉(zhuǎn)為30號(hào)
declare @d datetime
set @d=‘2003-5-31‘
select @d as 指定日期,
dateadd(month,-(month(@d)-1)%3,@d)-day(dateadd(month,-(month(@d)-1)%3,@d))+1 as 季度的第一天
-- [思路:分別求出年月日在轉(zhuǎn)為日期型]
declare @t smalldatetime
select @t = ‘2001-9-30‘
select cast(cast(year(@t) as varchar) + ‘-‘ + cast(3*datepart(q,@t)-2 as varchar) + ‘-1‘ as datetime)
--求當(dāng)前的日期季度的第一天
select cast(cast(year(getdate()) as varchar) + ‘-‘ + cast(3*datepart(q,getdate())-2 as varchar) + ‘-1‘ as datetime)
7. 時(shí)間重疊度的問(wèn)題?
出處:http://expert.csdn.net/Expert/topic/2806/2806966.xml?temp=.5277979
描述:
create table #a(id int identity(1,1),date1 datetime,date2 datetime)
insert #a select ‘2004-02-29 16:45:00‘,‘2004-02-29 20:45:00‘
union all select ‘2004-02-29 18:45:00‘,‘2004-02-29 22:45:00‘
union all select ‘2004-03-01 10:45:00‘,‘2004-03-01 13:45:00‘
union all select ‘2004-03-01 13:45:00‘,‘2004-03-01 16:45:00‘
union all select ‘2004-03-01 13:47:00‘,‘2004-03-01 14:25:00‘
union all select ‘2004-03-01 16:45:00‘,‘2004-03-01 19:15:00‘
union all select ‘2004-03-01 17:45:00‘,‘2004-03-01 18:55:00‘
union all select ‘2004-03-01 18:45:00‘,‘2004-03-01 21:45:00‘
select *from #a
我現(xiàn)在要找出時(shí)間上重疊超過(guò)1個(gè)小時(shí)的所有記錄!
比如第1、2條:一個(gè)是從16:45---20:45,第二條是從18:45---22:45時(shí)間上重疊了2個(gè)小時(shí),所以這兩條都要取出,其它的也是一樣的規(guī)則!
date2-date1小于1小時(shí)的不用考慮,如第5條??梢韵葎h除該條,記錄是按date1排序的!
所以最終的結(jié)果要為:
id date1 date2
----------- --------------------------- ---------------------------
1 2004-02-29 16:45:00.000 2004-02-29 20:45:00.000
2 2004-02-29 18:45:00.000 2004-02-29 22:45:00.000
6 2004-03-01 16:45:00.000 2004-03-01 19:15:00.000
7 2004-03-01 17:45:00.000 2004-03-01 18:55:00.000
解決思路:
實(shí)例:
--方案一:[作者:“victorycyz(中海,干活去了,不在CSDN玩。)”]
select distinct a.*
from #a a , #a b
where a.id<>b.id and
a.date1
(case when a.date2>b.date2 then b.date2 else a.date2 end)-
(case when a.date1>b.date1 then a.date1 else b.date1 end)>1/24.0
--方案二:[作者:“j9988(j9988)”]
select * from #a A where
exists(select 1 from #a
where id<>A.id
and dateadd(minute,60,date1) and (date1 between A.date1 and A.date2) and abs(datediff(minute,date1,A.date2))>=60) or exists(select 1 from #a where id<>A.id and dateadd(minute,60,A.date1) and (A.date1 between date1 and date2) and abs(datediff(minute,A.date1,date2))>=60)