1.sql題描述
話說有一個日志表,只有兩列,分別是連續id和num 至于啥意思,把它當金額把,現在想知道連續次數3次及以上的num,資料如下
| id | num |
|---|---|
| 1 | 1 |
| 2 | 1 |
| 3 | 1 |
| 4 | 2 |
| 5 | 3 |
| 6 | 4 |
| 7 | 4 |
| 8 | 4 |
那么結果只有1,4滿足條件,問這個sql該怎么寫?
2.思路和解法
分析:題目簡單,沒有歧義,能看得懂,像連續幾次的這種問題一定是用到視窗函式,首先想到的是排名row_number 然后lag 怎么體現連續呢,肯定是需要用到一個排序的id,由于題目給了id是連續遞增的,可以省去row_number了
所以第一步,上lag,結果就是如下:
| id | num | lagid |
|---|---|---|
| 1 | 1 | null |
| 2 | 1 | 0 |
| 3 | 1 | 0 |
| 4 | 2 | 1 |
| 5 | 3 | 1 |
| 6 | 4 | 1 |
| 7 | 4 | 0 |
| 8 | 4 | 0 |
得到lagid后,連續怎么用呢,首先只有為0的才滿足條件,所以可以做一個篩選,結果就如下表去掉xxx的,下面觀察0的行,怎么區分3 行的 0 和 7行的 0呢,想到使用新分組,rid 這樣就把lagid 相同,num相同的排序,最后再加一列,id-rid 相同的分為一組
| id | num | lagid | rid | gid |
|---|---|---|---|---|
| 1 | 1 | null xxx | ||
| 2 | 1 | 0 | 1 | 1 |
| 3 | 1 | 0 | 2 | 1 |
| 4 | 2 | 1 xxx | ||
| 5 | 3 | 1 xxx | ||
| 6 | 4 | 1 xxx | ||
| 7 | 4 | 0 | 1 | 6 |
| 8 | 4 | 0 | 2 | 6 |
-- 完整sql
## 解法1
SELECT num
FROM
(SELECT id,
num,
lagid,
(id-row_number() over(PARTITION BY num, lagid
ORDER BY id)) AS gid
FROM
(SELECT id,
num,
num- lag(num) (OVER PARTITION BY 1
ORDER BY id) AS lagid) tmp1
WHERE lagid=0 ) tmp2
GROUP BY num,
gid
HAVING count(*) >= 2
## 解法2
select
num,
gid,
count(1) as c
from
(
select
id,
num,
id-row_number() over(PARTITION BY num ORDER BY id) as gid
from
(select * from logs order by num,id) a
) b
group by num,gid
后面想到了更好的,其實不用lag,也不用order by 全域排序,id 的作用和日期一樣,一般是用來配合row_number來解決連續問題的,所以row_number必不可少,那么可以這樣寫(神他媽簡單是不是,別想復雜了):
SELECT num,
gid
FROM
(SELECT num,
id-row_number() OVER (PARTITION BY num
ORDER BY id) gid
FROM logs)
GROUP BY num,
gid
HAVING count(1) >= 3
3. Java題描述
首先,給你一個初始陣列 arr,然后,每天你都要根據前一天的陣列生成一個新的陣列,第 i 天所生成的陣列,是由你對第 i-1 天的陣列進行如下操作所得的:假如一個元素小于它的左右鄰居,那么該元素自增 1,假如一個元素大于它的左右鄰居,那么該元素自減 1,
首、尾元素 永不 改變,
過些時日,你會發現陣列將會不再發生變化,請回傳最終所得到的陣列,
示例 1:
輸入:[6,2,3,4]
輸出:[6,3,3,4]
解釋:
第一天,陣列從 [6,2,3,4] 變為 [6,3,3,4],
無法再對該陣列進行更多操作,
示例 2:
輸入:[1,6,3,4,3,5]
輸出:[1,4,4,4,4,5]
解釋:
第一天,陣列從 [1,6,3,4,3,5] 變為 [1,5,4,3,4,5],
第二天,陣列從 [1,5,4,3,4,5] 變為 [1,4,4,4,4,5],
無法再對該陣列進行更多操作,
3.3 分析和解法
-
首先考慮一輪遍歷怎么寫,應該很簡單把,思路就是一個大小為3的視窗
-
用一個flag來標志每一輪是否有改過資料,那么代碼如下:
public int[] get(int[] input) {
if (input == null || input.length <=2)
return input;
boolean flag = false;
do {
flag = false;
for (int i=1;i+1 < input.length;i++){
if (input[i] < input[i+1] && input[i] < input[i-1] ) {
input[i] +=1;
if (!flag)
flag = true;
}
if (input[i] > input[i+1] && input[i] > input[i-1] ) {
input[i] -=1;
if (!flag)
flag = true;
}
}
} while(flag)
return input;
}
吳邪,小三爺,混跡于后臺,大資料,人工智能領域的小菜鳥,
更多請關注

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/230933.html
標籤:其他
下一篇:基于done檔案的資料監控-理論
