實戰:SQL sever如何實現同一列上下行運算?

2020-12-11 IT圈不亂

今天講講資料庫SQL server的相關知識,如果要將一個表裡的兩列進行運算,那麼我們可以直接用欄位進行運算,如A+B或A-B,其中A和B是兩個不同列的欄位名。

SQL Server 知識

但是在項目中,有時候我們會遇到一些棘手的問題,做數據處理的時候,可能需要實現同一列的上下行運算。那麼在此樓主提供兩種思路:

一、SQL sever2012以上版本,可以用LAG函數。LAG的作用是,從當前行向下偏移指定的行數。 在 SELECT 語句中使用此分析函數可將當前行中的值與先前行中的值進行比較。使用語法如下:

LAG (scalar_expression [,offset] [,default]) OVER ( [ partition_by_clause ] order_by_clause )

其中,scalar_expression是指要根據指定偏移量返回的值。 這是一個返回單個(標量)值的任何類型的表達式,不能為分析函數。offset指當前行(從中獲得取值)後的行數。 如果未指定,則默認值為 1。 OVER為開窗函數,LAG函數必須與開窗函數一起使用。為了說明更加具體一點,我們做個測試表,取名為T:

建立測試表

然後執行SQL語句:SELECT ID,NUM,LAG(NUM) OVER (PARTITION BY ID ORDER BY NUM) AS OneArgs,LAG(NUM,1) OVER (PARTITION BY ID ORDER BY NUM) AS TowArgs,LAG(NUM,2,0) OVER (PARTITION BY ID ORDER BY NUM) AS ThressArgsFROM T,再看結果:

偏移後的數據顯示

從上面的示例中我們可以看出:

針對列OneArgs,組內的NUM列的值默認向下偏移了一行,每組的第一行用NULL來代替

針對TowArgs,offset參數傳1,NUM的值也是向下偏移一行,結果和OneArgs一樣。

針對ThreeArgs,offset參數傳2,而且第三個參數將偏移後默認值NULL改成了0。

明白了LAG函數的原理,我們看看怎麼實現上下行相加的運算:

SQL語句:SELECT ID,NUM,

NUM+LAG(NUM,1,0) OVER (PARTITION BY ID ORDER BY NUM) AS ResultFROM T

同列上下行相加運算

注意:第一行因為默認是0,所以每組第一行的結果是NUM+0=NUM

與LAG函數相對應的,還有個函數叫LEAD,此函數與LAG函數剛剛相反,它是向上偏移指定的行數,默認是1行。使用語法同LAG函數類似,此處不再贅述,直接看結果:

LEAD函數執行結果向上偏移一行

那麼我們很容易解答一個問題:如何求解同組內上下兩行的差?語句如下:

SELECT ID,NUM,LEAD(NUM,1,0) OVER (PARTITION BY ID ORDER BY NUM)-NUM AS ResultFROM T

同列上下行相減運算

運算規則可以自己寫,主要是要弄明白你想讓數據向上偏移還是向下偏移。

二、SQL sever2012以下版本,嘗試用臨時表拆分數據之後再比對的方式。

以上面的表為例,首選需要做個臨時表,這個錶帶有唯一標示號,我們取欄位名為xh:

做出新的臨時表

再執行SQL語句:SELECT a.ID,a.NUM,b.NUM-a.NUM FROM TA a

left join (SELECT xh-1 as xh,ID,NUM from TA) b on a.xh =b.xh AND a.ID=b.ID

用臨時表的方法算出結果

總結:這兩種雖然寫法和語法都不一樣,但是思路是一樣的,就是先把一個列的數據向上或向下偏移,偏移後形成一個新的列,然後再進行兩列的運算,得到我們想要的結果。

好了今天的SQL知識暫時就分享到這裡,有疑問的讀者可以評論區留言,歡迎關注我的百家號"IT圈不亂"。

相關焦點

  • 基於SQL思維的DAX實戰
    基於SQL思維使用DAX解決實戰問題作者:天行學習掌握DAX語言的初期,尤其是剛開始嘗試將DAX應用到實戰中時,書上的、別人的例子永遠是別人的,自己工作中的問題還是找不到如何下手。 其實如果有SQL的使用經驗,上手DAX就相對容易很多,尤其對於工作實踐中的複雜邏輯,使用SQL思維,進行逐步分解,然後用DAX的方式去具體實現,確實是高效的解決方法。 正好星球學友Mars懸賞徵求「一次性解決率「的方案,藉此機會,我們一起來實踐一下基於SQL思維如何使用DAX來解決這個問題。
  • SQL Server 動態行轉列(參數化表名、分組列、行轉列欄位、欄位值)
    一.本文所涉及的內容(Contents)本文所涉及的內容(Contents)背景(Contexts)實現代碼(SQL Codes)方法一:使用拼接SQL,靜態列欄位;方法二:使用拼接SQL,動態列欄位;方法三:使用PIVOT關係運算符,靜態列欄位;方法四:使用PIVOT關係運算符
  • 高效的SQL盲注_位運算(一)
    > 0x00 前言本篇文章主要探討在mysql中SQL盲注如何高效的得到數據
  • FlinkSQL窗口函數篇:易理解與實戰案例
    目的是從最容易理解與近實戰案例方式去讓讀者獲得收益。本篇是FlinkSQL實戰的開篇,歡迎收藏,轉發與持續關注。timecol: 是一個列描述符指示應該映射到哪個時間的屬性列。size: 是一個持續時間指定窗口的寬度。用法與場景用法窗口大小三分鐘,允許遲到一分鐘。
  • 【SQL】行轉列
    Course,75 AS Grade)SELECT * FROM StudentNameCourseGrade劉得華語文54劉得華數學95劉得華英語60吳延祖語文98吳延祖數學47吳延祖英語7501 通過case when和聚合函數實現
  • SparkSQL基礎及實戰練習
    }} SparkSQL實戰準備數據8.查詢分數大於70,小於90的Sno列。9.查詢所有學生的Sname、Cno和Degree列。10.查詢所有學生的Sno、Cname和Degree列。11.查詢所有學生的Sname、Cname和Degree列。12.查詢「95033」班學生的平均分。13.查詢所有選修「計算機導論」課程的「女」同學的成績表。14.查詢選修「3-105」課程的成績高於「109」號同學成績的所有同學的記錄。
  • 如何學習SQL語言
    入門要讓初學者看懂才是最重要的,而不是整那些高大上的東西。2)如何對數據分組?3)如何對分組結果指定條件?4)用 SQL 解決業務問題的套路是什麼?5)如何對查詢結果排序?6)如何看懂 SQL 報錯信息?
  • 5分鐘學會SQL SERVER行轉列、列轉行,PIVOT操作
    PIVOT語法PIVOT示例UNPIVOT語法UNPIVOT示例PIVOT和UNPIVOTPIVOT 通過將表達式中的一個列的唯一值轉換為輸出中的多列(即行轉列),來輪替表值表達式。PIVOT 在需要對最終輸出所需的所有剩餘列值執行聚合時運行聚合。與 PIVOT 執行的操作相反,UNPIVOT 將表值表達式的列輪換為行(即列轉行)。但是需要注意的是,UNPIVOT 並不完全是 PIVOT 的逆操作。PIVOT 執行聚合,並將多個可能的行合併為輸出中的一行。
  • 如何利用Python實現SQL自動化?
    本文將為你展示如何操作。只要編寫好這個代碼,通過Python 連接到SQL 僅需:sql = Sql('database123')很簡單對麼?同時發生了幾件事,下面將對此代碼進行剖析。class Sql:首先要注意,這個代碼包含在一個類中。筆者發現這是合乎邏輯的,因為在此格式中,已經對此特定資料庫進行了增添或移除進程。若見其工作過程,思路便能更加清晰。
  • 資料庫SQL腳本優化
    語句儘可能簡單點,一個大的sql要是在滿足業務需求的情況下可以分解為多個小sql是最好的。因為一個sql只能在一個cpu運算。(前兩天就有一個超大的sql,最後通過分解成三個小的sql,通過中間表傳遞實現最終需求)6、or改寫成in,因為or的效率是n級別的,in的效率是log(n)級別的,in的個數儘量不要太多,最好控制在200以內7、避免在where條件列上不乾淨,比如說SELECT id WHERE age + 1 = 10,或者對age
  • 聊聊 sql 優化的 15 個小技巧
    sql 優化是一個大家都比較關注的熱門話題,無論你在面試,還是工作中,都很有可能會遇到。如果某天你負責的某個線上接口,出現了性能問題,需要做優化。那麼你首先想到的很有可能是優化 sql 語句,因為它的改造成本相對於代碼來說也要小得多。
  • PySpark SQL——SQL和pd.DataFrame的結合體
    那麼,在已經有了RDD的基礎上,Spark為什麼還要推出SQL呢?為此,Spark團隊還專門為此發表論文做以介紹,原文可查找《Spark SQL: Relational Data Processing in Spark》一文。
  • 如何使用 SQL Server FILESTREAM 存儲非結構化數據?
    它不是VARBINARY (MAX)這樣的數據類型,而是通過VARBINARY列設置的attribute/property,表明數據應該被直接存儲在文件系統上。這些數據仍然是系統的組成部分,並保持事務一致性。以下是FILESTREAM的一些特徵:二進位數據作為單獨的文件存儲在資料庫之外。
  • SQL Server 2014 可更新聚集列存儲索引
    在SQL Server 2012中一旦將非聚集列存儲索引建立在某個表上時,該表將變為只讀,即使在數據倉庫中使用列索引,每次更新或添加數據也會是一件非常瑣碎的事。SQL Server 2014中的可更新聚集列索引則解決了該問題。
  • 最基本的SQL語句大全
    A: UNION 運算符 UNION 運算符通過組合其他兩個結果表(例如 TABLE1 和 TABLE2)並消去表中任何重複行而派生 出一個結果表。  為了取出幾條隨機選擇的記錄並存放在同一recordset內,你可以存儲三個隨機數,然後查詢 資料庫獲得匹配這些數字的記錄: sql = "Select * FROM Customers Where ID = " & RNumber & " or ID = " & RNumber2 & " or ID = " & RNumber3
  • 數據分析利器 pandas 系列教程(四):對比 sql 學 pandas
    df['sex']=='male'的結果就是一個布爾值,然後這個布爾值再與 df['grade'] 作 & 運算,這樣就報錯了。所以必須 reset_index 下,這個函數有兩個值得注意的參數 inplace 和 drop,inplace 在 強大的 DataFrame 就講過,如果原地修改就設置為 True;至於這個 drop ,設置為 False 則 index 列會被還原為普通列,否則的話就直接丟失,這裡我們設置為
  • 續 | 《SQL基礎教程》學習筆記
    from Productwhere purchase_price not in (500,2800,5000,null);--結果是什麼都沒有,使用子查詢作為not in 的參數時,子查詢的返回值也不能是null集合在數學領域表示"(各種各樣)事物的總和",在資料庫領域表示記錄(行)的集合,集合運算是對滿足同一規則的記錄的進行加減等四則運算
  • Python也能寫SQL,組合查詢~
    ,其實在數據分析時,使用最多的功能是數據分組或者是數據透視功能,Excel中插入數據透視表,Python中使用pivot_table函數,而SQL中使用group by函數,下面一起學習group by的分組功能。
  • hive sql 優化心得
    如何寫好一個hql作為一個數據開發工程師,hive sql是我們必備的技能,可能大家都知道一些基本的優化方法(例如:使用分區、小表join大表、不使用distinct、where條件儘量寫到子查詢裡面減少數據量等等),但是你有沒有想過為什麼?是不是真的對執行效率有提升。
  • 美團開源 SQL 優化工具 SQLAdvisor,與內部版本保持一致
    Join 條件會存在當層的葉子節點上,如果左右節點都是葉子節點,會存在右葉子節點。每一個非葉子節點代表一次 Join 的結果。上述實現時,涉及的函數為:mysql_sql_parse_join(TABLE_LIST join_table) mysql_sql_parse_join(Item join_condition) ,主要流程圖如下: