在論壇中出現的比較難的sql問題:31(row_number函式+子查詢 月環比計算)
阿新 • • 發佈:2019-01-23
最近,在論壇中,遇到了不少比較難的sql問題,雖然自己都能解決,但發現過幾天后,就記不起來了,也忘記解決的方法了。
2 Z
3 Z
4 L
5 Z
6 L
7 L
8 L SQL2000資料庫,查詢結果
FLAG-Z FLAG-L
1 4
2 6
3 7
4 8
我的解法,最關鍵的是如何生成行號,分別對不同的資料產生行號,由於是2000資料庫,稍微有點麻煩:
如果是2005資料庫,那麼就簡單多了:
所以,覺得有必要記錄下來,這樣以後再次碰到這類問題,也能從中獲取解答的思路。
1、同一表兩條記錄同一欄位做比較的問題
一張sql表中的最新兩條記錄裡的兩個數字型別欄位對比,最後一條比上一條的值大則輸出上升,一樣大輸出持平 比上一條小則輸出下降 這個資料查詢怎麼寫?
if object_id('[tb]') is not null drop table [tb] go create table [tb]([Id] int,[Name] varchar(3),[Result] int,[Date] datetime) insert [tb] select 1,'001',90,'2013-11-10' union all select 2,'002',85,'2013-11-10' union all select 3,'003',87,'2013-11-10' union all select 4,'001',95,'2013-11-15' union all select 5,'002',83,'2013-11-15' union all select 6,'003',89,'2013-11-15' union all select 7,'001',92,'2013-11-20' union ALL select 8,'002',83,'2013-11-20' union all select 9,'003',88,'2013-11-20' go ;with t as ( select *, ROW_NUMBER() over(partition by [Name] order by [Date] desc) rownum from tb ) select t1.Name,t1.Result, case when t1.[Result] > t2.[Result] then '上升' when t1.[Result] = t2.[Result] then '持平' when t1.[Result] < t2.[Result] then '下降' end flag from t t1 left join t t2 on t1.Name = t2.Name and t1.rownum = t2.rownum - 1 and t2.rownum = 2 where t1.rownum = 1 /* Name Result flag 001 92 下降 002 83 持平 003 88 下降 */
2、求sql,看似簡單。
http://bbs.csdn.net/topics/390620423
No FLAG
1 Z2 Z
3 Z
4 L
5 Z
6 L
7 L
8 L SQL2000資料庫,查詢結果
FLAG-Z FLAG-L
1 4
2 6
3 7
4 8
我的解法,最關鍵的是如何生成行號,分別對不同的資料產生行號,由於是2000資料庫,稍微有點麻煩:
drop table t create table t(No int,FLAG varchar(10)); insert into t select 1 , 'Z' union all select 2 , 'Z' union all select 3 , 'Z' union all select 4 , 'L' union all select 5 , 'Z' union all select 6 , 'L' union all select 7 , 'L' union all select 8 , 'L' select z.no,L.no from ( select *, (select count(*) from t t2 where t2.no <= t1.no and t2.flag = 'z') as rownum from t t1 where flag = 'z' )z inner join ( select *, (select count(*) from t t2 where t2.no <= t1.no and t2.flag = 'L') as rownum from t t1 where flag = 'L' )L on z.rownum = L.rownum /* no no 1 4 2 6 3 7 5 8 */
如果是2005資料庫,那麼就簡單多了:
drop table t
create table t(No int,FLAG varchar(10));
insert into t
select 1 , 'Z' union all
select 2 , 'Z' union all
select 3 , 'Z' union all
select 4 , 'L' union all
select 5 , 'Z' union all
select 6 , 'L' union all
select 7 , 'L' union all
select 8 , 'L'
select t1.no,t2.no
from
(
select *,
row_number() over(partition by flag order by no) as rownum
from t
)t1
inner join
(
select *,
row_number() over(partition by flag order by no) as rownum
from t
)t2
on t1.rownum = t2.rownum
and t1.flag = 'z'
and t2.flag = 'L'
/*
no no
1 4
2 6
3 7
5 8
*/