DATEADD 関数と DATEDIFF 関数の組み合わせで閏年もしっかり考慮

2024-04-14

SQL Server で、生年月日と現在の日付に基づいて年齢を計算するには、いくつかの方法があります。ここでは、最も一般的で使いやすい 2 つの方法をご紹介します。

方法 1: DATEDIFF 関数を使用する

DATEDIFF 関数は、2 つの日付間の差を計算するために使用されます。年齢を計算するには、DATEDIFF 関数を使用して、生年月日と現在の日付の差を年単位で計算します。

SELECT DATEDIFF(YEAR, BirthDate, GETDATE()) AS Age
FROM Customers;

このクエリは、Customers テーブル内のすべての顧客の年齢を計算し、Age という名前の列に結果を格納します。

DATEADD 関数は、指定された日付に期間を追加するために使用されます。年齢を計算するには、DATEADD 関数を使用して、生年月日に経過した年数を追加し、現在の日付と比較します。

SELECT DATEADD(YEAR, DATEDIFF(YEAR, BirthDate, GETDATE()), BirthDate) AS CurrentAge
FROM Customers;

補足

  • 上記の例では、BirthDate 列が Customers テーブルにあることを前提としています。使用する列名が異なる場合は、それに応じてクエリを修正する必要があります。
  • DATEDIFF 関数は、2 つの入力パラメータ間の日付差を計算します。最初の入力パラメータは、結果を表現する単位を指定します。この場合、結果は年単位で表されるため、YEAR を使用します。2 番目の入力パラメータは、比較する 2 つの日付を指定します。この場合、最初の入力パラメータは BirthDate 列、2 番目の入力パラメータは GETDATE() 関数です。
  • DATEADD 関数は、指定された日付に期間を追加します。最初の入力パラメータは、追加する期間の単位を指定します。この場合、期間は年単位で表されるため、YEAR を使用します。2 番目の入力パラメータは、期間を追加する日付を指定します。この場合、最初の入力パラメータは DATEDIFF(YEAR, BirthDate, GETDATE()) 関数によって返される値です。3 番目の入力パラメータは、期間を追加する基準となる日付を指定します。この場合、基準となる日付は BirthDate 列です。

その他の考慮事項

  • 閏年を考慮する場合は、より複雑な計算が必要になります。詳細については、SQL Server のドキュメントを参照してください。
  • 年齢を月単位または日単位で計算することもできます。これを行うには、DATEDIFF 関数と DATEADD 関数の他の単位を使用します。



CREATE TABLE Customers (
  CustomerID INT IDENTITY PRIMARY KEY,
  FirstName VARCHAR(50),
  LastName VARCHAR(50),
  BirthDate DATE
);

INSERT INTO Customers (FirstName, LastName, BirthDate)
VALUES ('John', 'Doe', '1980-01-01'),
       ('Jane', 'Doe', '1985-07-14'),
       ('Peter', 'Jones', '1990-12-25');
SELECT CustomerID, FirstName, LastName, BirthDate, DATEDIFF(YEAR, BirthDate, GETDATE()) AS Age
FROM Customers;

結果

CustomerIDFirstNameLastNameBirthDateAge
1JohnDoe1980-01-0144
2JaneDoe1985-07-1438
3PeterJones1990-12-2533
SELECT CustomerID, FirstName, LastName, BirthDate, DATEADD(YEAR, DATEDIFF(YEAR, BirthDate, GETDATE()), BirthDate) AS CurrentAge
FROM Customers;
CustomerIDFirstNameLastNameBirthDateCurrentAge
1JohnDoe1980-01-012024-01-01
2JaneDoe1985-07-142024-07-14
3PeterJones1990-12-252024-12-25

説明

  • 上記のサンプルコードは、Customers テーブル内のすべての顧客のレコードをループ処理します。
  • 各レコードについて、以下の処理が行われます。
    • FirstNameLastNameBirthDate 列の値を取得します。
    • DATEDIFF(YEAR, BirthDate, GETDATE()) 関数を使用して、生年月日と現在の日付の差を年単位で計算します。
    • DATEADD(YEAR, DATEDIFF(YEAR, BirthDate, GETDATE()), BirthDate) 関数を使用して、生年月日に経過した年数を追加し、現在の日付を計算します。
    • 取得した値を、CustomerIDFirstNameLastNameBirthDateAge または CurrentAge 列の値とともに新しい行として結果セットに追加します。

このサンプルコードは、SQL Server で生年月日と現在の日付に基づいて年齢を計算する方法を理解するための出発点として使用できます。必要に応じて、独自の要件に合わせてコードをカスタマイズすることができます。




SQL Server で生年月日と現在の日付に基づいて年齢を計算するその他の方法

この方法は、MONTH 関数と YEAR 関数を使用して、生年月日の月と年を抽出し、現在の日付の月と年と比較することで、年齢を計算します。

SELECT
  CustomerID,
  FirstName,
  LastName,
  BirthDate,
  YEAR(GETDATE()) - YEAR(BirthDate) - (
    CASE
      WHEN MONTH(GETDATE()) < MONTH(BirthDate) THEN 1
      ELSE 0
    END
  ) AS Age
FROM Customers;

この方法は、CAST 関数を使用して、生年月日を datetime データ型に変換してから、DATEDIFF 関数を使用して、現在の日付との差を計算します。

SELECT
  CustomerID,
  FirstName,
  LastName,
  BirthDate,
  DATEDIFF(YEAR, CAST(BirthDate AS DATETIME), GETDATE()) AS Age
FROM Customers;

この方法は、ROW_NUMBER 関数と OVER 句を使用して、各顧客の行番号を計算し、その行番号を使用して、生年月日から現在の日付までの経過年数を計算します。

SELECT
  CustomerID,
  FirstName,
  LastName,
  BirthDate,
  ROW_NUMBER() OVER (ORDER BY BirthDate) AS RowNumber,
  DATEDIFF(YEAR, BirthDate, GETDATE()) - (
    MAX(CASE WHEN RowNumber < RowNumberOver(PARTITION BY BirthDate ORDER BY BirthDate) THEN 1 ELSE 0 END)
    OVER (PARTITION BY BirthDate ORDER BY BirthDate)
  ) AS Age
FROM Customers;

各方法の比較

方法長所短所
DATEDIFF 関数を使用するシンプルでわかりやすい閏年を考慮していない
DATEADD 関数と DATEDIFF 関数を使用する閏年を考慮しているDATEDIFF 関数を使用するよりも複雑
MONTH 関数と YEAR 関数を使用するシンプルでわかりやすい閏年を考慮していない
CAST 関数と DATEDIFF 関数を使用する閏年を考慮しているCAST 関数の使用により、パフォーマンスが若干低下する可能性がある
ROW_NUMBER 関数と OVER 句を使用する複雑なクエリで使用できる他の方法よりも複雑

SQL Server で生年月日と現在の日付に基づいて年齢を計算するには、さまざまな方法があります。最良の方法 は、特定の要件とパフォーマンス要件によって異なります。

上記の方法は、あくまでも出発点として提供されています。必要に応じて、独自の要件に合わせてコードをカスタマイズすることができます。


sql sql-server t-sql


謎が解けた! SQL Server で CAST する際に VARCHAR のデフォルト長が 30 な理由

歴史的な理由:過去の SQL Server バージョンでは、VARCHAR の最大長が 30 でした。パフォーマンス:30 は、多くの一般的な文字列操作にとって十分な長さであり、パフォーマンスを犠牲にしない妥協点です。互換性:多くの既存のコードは VARCHAR(30) を前提としているため、変更すると互換性の問題が発生する可能性があります。...


SQL Server テーブル操作の基礎知識:テーブル参照、JOIN、サブクエリ、ビュー、ストアド プロシージャ

SQL Server における @、#、## は、それぞれ異なる用途を持つ特殊なプレフィックス記号です。 データベース操作を行う際に、それぞれの役割を理解することが重要です。@ 記号@ 記号は、パラメータを表すために使用されます。 パラメータは、クエリの実行時に渡される値を保持する変数のようなものです。 パラメータを使用することで、クエリをより柔軟かつ再利用可能にすることができます。...


PostgreSQLにおけるインデックス:データ挿入前 vs. 後、最適なタイミングは?

多くの場合、データ挿入後にインデックスを作成することをお勧めします。理由データ量が少ないうちはインデックスのメリットが小さい: データ量が少ないうちは、テーブルスキャンの方がインデックスよりも効率的な場合があります。インデックス作成にはコストがかかる: インデックス作成には処理時間がかかり、ディスク領域も消費されます。データ量が少ないうちは、このコストがパフォーマンスに与える影響が大きくなります。...


NOT EXISTS、EXISTS、LEFT JOIN、IN演算子:外部キーと行選択

NOT EXISTS を使用すると、別のテーブルに一致するエントリがない行を選択できます。 構文は以下のようになります。この例では、table1 から table2 に一致するエントリがない行を選択します。 table1. foreign_key_column は table2...


RETURNING 句でシンプルに取得:MariaDB 8.0 以降で利用可能なエレガントな方法

RETURNING 句を使用するMariaDB 8.0 以降では、UPDATE ステートメントに RETURNING 句を追加することで、更新された行を直接取得できます。これは、最もシンプルで効率的な方法です。上記の例では、customers テーブルの id が 123 の行を更新し、更新された行のすべての列を返します。...