[轉]MONTHS_BETWEEN Function - Oracle to SQL Server Migration

来源:http://www.cnblogs.com/freeliver54/archive/2017/09/14/7521125.html
-Advertisement-
Play Games

本文轉自:http://www.sqlines.com/oracle-to-sql-server/months_between In Oracle, MONTHS_BETWEEN(date1, date2) function returns the number of months between ...


本文轉自:http://www.sqlines.com/oracle-to-sql-server/months_between

In Oracle, MONTHS_BETWEEN(date1, date2) function returns the number of months between two dates as a decimal number. 

Note that SQL Server DATEDIFF(month, date2, date1) function does not return exactly the same result, and you have to use an user-defined function if you need to fully emulate the Oracle MONTHS_BETWEEN function (see UDF's code below).  

Oracle:

  ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD';
 
  -- 1-day difference  
  SELECT MONTHS_BETWEEN('2013-03-01', '2013-02-28') FROM dual;
  # 0.129032258
 
  -- Still 1-day difference but the result is different
  SELECT MONTHS_BETWEEN('2013-03-02', '2013-03-01') FROM dual;
  # 0.32258065

SQL Server:

DATEDIFF always returns an integer result.

  -- 1-day difference, but 1 month returned (!)
  SELECT DATEDIFF(month, '2013-02-28', '2013-03-01');
  # 1
 
  -- Still 1-day difference but the result is different
  SELECT DATEDIFF(month, '2013-03-01', '2013-03-02');
  # 0

Also note that MONTHS_BETWEEN and DATEDIFF have different order of parameters.

Oracle MONTHS_BETWEEN in Detail

MONTHS_BETWEEN returns the number of full months between dates and a fractional part. 

An integer value is returned only if:

  • Both dates specify the same day of the month (February 13 and March 13 i.e.)
  • Both dates are the last days of the months (January 31 and April 30 i.e.)

Oracle:

  -- Between March 13 and February 13
  SELECT MONTHS_BETWEEN('2013-03-13', '2013-02-13') FROM dual;
  # 1
 
  -- Between April 30 and January 31
  SELECT MONTHS_BETWEEN('2013-04-30', '2013-01-31') FROM dual;
  # 3

Fractional Part

The fractional part is calculated using the following formula:

Condition Fractional Part Calculation
If day_of_date1 > day_of_date2 (day_of_date1 - day_of_date2) / 31
If day_of_date1 < day_of_date2 (31 - day_of_date2 + day_of_date1) / 31

Note that when MONTHS_BETWEEN calculates the fractional part, it considers that all months have 31 days. 

Consider the following examples:

Oracle:

 -- 1-day difference  
  SELECT MONTHS_BETWEEN('2013-03-01', '2013-02-28') FROM dual;
  # 0.129032258

Although there is just 1-day difference between February 28, 2013 and March 01, 2013, MONTHS_BETWEEN considers Feb 29, Feb 30, Feb 31 and Mar 01:

(31 - 28 + 1) / 31 =  0.129032258

Another example:

  -- Still 1-day difference but the result is different
  SELECT MONTHS_BETWEEN('2013-03-02', '2013-03-01') FROM dual;
   # 0.32258065

Now the fractional part is calculated as follows:

(2 - 1) / 31 = 0.32258065

SQL Server User-Defined Function to Emulate Oracle MONTHS_BETWEEN

You can use the following user-defined function to emulate Oracle MONTHS_BETWEEN function:

SQL Server:

   CREATE FUNCTION MONTHS_BETWEEN (@date1 DATETIME, @date2 DATETIME) 
	RETURNS FLOAT
   AS
   /******************************************************************************
      PURPOSE: Emulate Oracle MONTHS_BETWEEN in SQL Server
 
      REVISIONS:
      Ver        Date             Author                                   Description
      ---------  ----------       ---------------                         ---------------------------
      1.1         2013-02-10  Dmitry Tolpeko (SQLines)       Created.
   ******************************************************************************/
   BEGIN
     DECLARE @months FLOAT = DATEDIFF(month, @date2, @date1);
 
     -- Both dates does not point to the same day of month
     IF DAY(@date1) <> DAY(@date2) AND
        -- Both dates does not point to the last day of month
        (MONTH(@date1) = MONTH(@date1 + 1) OR MONTH(@date2) = MONTH(@date2 + 1))
     BEGIN
        -- Correct to include full months only and calculate fraction
        IF DAY(@date1) < DAY(@date2)
          SET @months = @months + CONVERT(FLOAT, 31 - DAY(@date2) + DAY(@date1)) / 31 - 1;
        ELSE    
          SET @months = @months + CONVERT(FLOAT, DAY(@date1) - DAY(@date2)) / 31;
     END
 
     RETURN @months; 
   END;
   GO

Now you can use the UDF as follows:

SQL Server:

    -- 1-day difference  
  SELECT dbo.MONTHS_BETWEEN('2013-03-01', '2013-02-28');
  # 0.129032258
 
  -- Still 1-day difference but the result is different (as in Oracle)
  SELECT dbo.MONTHS_BETWEEN('2013-03-02', '2013-03-01');
  # 0.32258065

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 環境: A、B兩台伺服器分別安裝mysql-5.7.18服務端,配置成互為主從同步。 linux系統版本為CentOS7 A伺服器ip:192.168.1.7 主機名:test1 B伺服器ip:192.168.1.8 主機名:test2 (同一區域網下) 一、準備 1.修改主機名 命令:hostna ...
  • Oracle資料庫學習: 01.資料庫簡介: (1)文件型資料庫: Access Office組件: Foxpro (2)NoSql資料庫(泛指非關係型資料庫): NoSQL(NoSQL = Not Only SQL ),意即“不僅僅是SQL”,是一項全新的資料庫革命性運動,早期就有人提出,發展至2 ...
  • 原創文章,轉載請註明出處:http://www.cnblogs.com/weix-l/p/7521278.html; 若有錯誤,請評論指出,謝謝! 1. 聚合函數(Aggregate Function) MySQL(5.7 ) 官方文檔中給出的聚合函數列表(圖片)如下: 詳情點擊https://de ...
  • 昨天,一個大新聞爆出,MongoDB資料庫叕被攻擊了。就在上周末,三個黑客團夥劫持了MongoDB逾26000多台伺服器,其中規模最大的一組超過22000台。 “MongoDB啟示錄”再臨? 此次攻擊由安全專家Dylan Katz和Victor Gevers發現,被他們稱為是“MongoDB啟示錄” ...
  • 狀態名 作用域 詳細解釋 Aborted_clients Global 由於客戶端沒有正確關閉連接導致客戶端終止而中斷的連接數 Aborted_connects Global 試圖連接到MySQL伺服器而失敗的連接數 Binlog_cache_disk_use Global 使用臨時二進位日誌緩存但 ...
  • 需求: 如果表欄位的值為 0 則將其修改為1 ,如果表欄位的值為 1 則將其修改為 0。 方法一 方法二 方法三 ...
  • 一工廠的SQL Server資料庫伺服器上的YourSQLDba_LogBackups作業做事務日誌備份時,突然出現異常,異常的錯誤信息指向.NET Framework,出現這個問題時,一般我估計是該伺服器自動應用了.NET Framework的一些補丁導致,因為以前也碰到過這類錯誤,於是去檢查服務 ...
  • 通過servlet,jsp,mysql實現用戶顯示,功能模塊和後臺數據三個模塊分離 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...