勤怠や人事システムのレポートを作っていると、「Newport Plant – 10601 – L48 Production」のようなコードから、最初の拠点名だけをSQLで抜き出したくなる場面がよくあります。この記事では、Dayforce 付属の SQL エディタ(SQL Server 互換)で Location 列の「ハイフン左側だけ」を安全かつ効率良く抽出する方法と、同じことを Excel で行うテクニックまでまとめて解説します。
Location列から「ハイフン左側だけ」を取り出したい
まずは、今回のゴールをはっきりさせておきます。Location 列には次のような文字列が入っているとします。
Newport Plant - 10601 - L48 Production
Sandpoint - 13501 - AK Shore QA
このとき、欲しいのは先頭の「拠点名」だけです。
Newport Plant - 10601 - L48 Production→ Newport PlantSandpoint - 13501 - AK Shore QA→ Sandpoint
右側の「数字」「補足情報」は、レポートによっては不要なことも多く、拠点マスタと結合したり、拠点別で集計したりするために「Location のハイフン左側だけ」を別列として取り出したくなります。
ここでは Dayforce の SQL エディタ(SQL Server 互換)でこの処理を行うことを前提に、次の3パターンを紹介します。
- もっとも簡潔に書ける SUBSTRING + CHARINDEX + COALESCE パターン(推奨)
- 読みやすさ重視の CASE + LEFT + CHARINDEX パターン
- Excel で同じ処理を行うパターン(TEXTBEFORE / LEFT + FIND)
結論:まずはこの1行を覚える(SQL Server向け)
さっそくですが、Location 列からハイフンの左側だけを取り出す最短パターンは次のようになります。
SELECT
Location,
COALESCE(
SUBSTRING(Location, 0, CHARINDEX('-', Location)),
Location
) AS PlantName
FROM YourTable;
この1行をざっくり説明すると、
CHARINDEX('-', Location)… 先頭のハイフンが何文字目にあるかを取得SUBSTRING(Location, 0, その位置)… 先頭から「ハイフンの1文字手前」までを切り出しCOALESCE(…, Location)… ハイフンが見つからずNULL(もしくは空文字)になったときは元の Location を返す
という流れです。
実際に例を当てはめると、次のようなイメージになります。
| Location | CHARINDEX(‘-‘, Location) | SUBSTRING(Location, 0, 位置) | 最終結果(PlantName) |
|---|---|---|---|
| Newport Plant – 10601 – L48 Production | 14(例) | Newport Plant | Newport Plant |
| Sandpoint – 13501 – AK Shore QA | 11(例) | Sandpoint | Sandpoint |
| Head Office(ハイフンなし) | 0 | NULL または空文字 | Head Office(COALESCE で元の値) |
Dayforce の SQL エディタの挙動によっては、ハイフンが無い場合に SUBSTRING(Location, 0, 0) が NULL ではなく空文字 '' を返すこともありえます。その場合は、次のように NULLIF を組み合わせるとより安全です。
SELECT
Location,
COALESCE(
NULLIF(SUBSTRING(Location, 0, CHARINDEX('-', Location)), ''),
Location
) AS PlantName
FROM YourTable;
どちらのパターンでも、
- ハイフンあり → ハイフンの左側だけが返る
- ハイフンなし → Location 全体が返る
という結果になるように設計されています。
文字列関数の前提知識:CHARINDEX / SUBSTRING / LEFT / COALESCE / CASE
ここから先の解説をスムーズに理解するために、SQL Server 系でよく使う文字列関数の「おさらい」をしておきます。
| 関数 | 役割 | サンプル | 結果イメージ |
|---|---|---|---|
CHARINDEX | 指定した文字列が何文字目に現れるかを返す | CHARINDEX('-', 'AAA-BBB') | 4 |
SUBSTRING | 指定位置から指定文字数分だけ文字列を切り出す | SUBSTRING('ABCDEF', 2, 3) | BCD |
LEFT | 左から指定文字数分だけ切り出す | LEFT('ABCDEF', 3) | ABC |
COALESCE | 複数の値のうち、最初に NULL でないものを返す | COALESCE(NULL, '', 'X') | 空文字(”) |
CASE | 条件によって返す値を切り替える | CASE WHEN 1=1 THEN 'A' ELSE 'B' END | A |
今回のテーマである「ハイフン左側だけを抜き出す」は、
CHARINDEXで「区切り文字(-)」の位置を調べSUBSTRINGまたはLEFTで左側を切り出し- ハイフンが無いレコードに備えて
COALESCEやCASEでガードする
という3ステップに分解できます。
パターン1:もっとも簡潔な書き方(推奨)
あらためて、推奨パターンをもう一度整理します。
SELECT
Location,
COALESCE(
NULLIF(SUBSTRING(Location, 0, CHARINDEX('-', Location)), ''),
Location
) AS PlantName
FROM YourTable;
なぜ SUBSTRING の開始位置が 0 なのか?
SQL Server 系の SUBSTRING は「開始位置」「長さ」の2つを指定して取り出します。
SUBSTRING('ABCDEF', 1, 3)→ABCSUBSTRING('ABCDEF', 2, 3)→BCD
ここで、
- 開始位置に 0 を渡す
- 長さに
CHARINDEX('-', Location)を渡す
という少しトリッキーな書き方をすると、
- ハイフンの位置が
nのとき、結果は「先頭からn-1文字分」になる
という挙動になり、ちょうど「ハイフンの1文字手前まで」を取り出せます。つまり、
SUBSTRING(Location, 0, CHARINDEX('-', Location))
だけで、LEFT(Location, CHARINDEX('-', Location) - 1) と同じような働きをしてくれるわけです。
ハイフンが無い場合への備え(COALESCE / NULLIF)
問題は、Location にハイフンが入っていない行です。
CHARINDEX('-', 'Head Office')→0SUBSTRING('Head Office', 0, 0)→ 空文字''(もしくはNULLの環境もあり)
拠点名にハイフンが入っていないのは異常ではなく、「その場合は Location 全体を返してほしい」ので、COALESCE と NULLIF を組み合わせて、
- SUBSTRING の結果が空文字(または NULL)のときだけ Location 全体を返す
という形にしています。
サンプルデータで確認する
一時テーブルを使って、Dayforce のクエリウィンドウ上でも簡単に動作確認ができます。
-- サンプルデータ
CREATE TABLE #t(Location nvarchar(100));
INSERT INTO #t (Location) VALUES
(N'Newport Plant - 10601 - L48 Production'),
(N'Sandpoint - 13501 - AK Shore QA'),
(N'Head Office'); -- ハイフンなし
-- 抽出クエリ
SELECT
Location,
COALESCE(
NULLIF(SUBSTRING(Location, 0, CHARINDEX('-', Location)), ''),
Location
) AS PlantName
FROM #t;
DROP TABLE #t;
結果イメージは次の通りです。
| Location | PlantName |
|---|---|
| Newport Plant – 10601 – L48 Production | Newport Plant |
| Sandpoint – 13501 – AK Shore QA | Sandpoint |
| Head Office | Head Office |
パターン2:読みやすさ重視の CASE + LEFT パターン
SUBSTRING を 0 から始めるトリックは短く書ける反面、「一瞬考えないと意味が分からない」デメリットもあります。チーム開発や将来の読みやすさを重視するなら、次のように LEFT + CASE を使った正攻法もおすすめです。
SELECT
Location,
CASE
WHEN CHARINDEX('-', Location) > 0 THEN
LEFT(Location, CHARINDEX('-', Location) - 1)
ELSE
Location
END AS PlantName
FROM YourTable;
この書き方は意味が非常に分かりやすく、
- ハイフンがある → ハイフン位置 – 1 文字分だけ LEFT で取り出す
- ハイフンがない → Location のまま返す
というロジックがそのまま読めます。
簡潔さ vs 読みやすさの比較
2つのパターンを比較すると次のようになります。
| パターン | サンプルコード | 特徴 |
|---|---|---|
| SUBSTRING + COALESCE(推奨) | COALESCE(NULLIF(SUBSTRING(Location, 0, CHARINDEX('-', Location)), ''), Location) | コードが短く、単純な抽出には最適。 SUBSTRING の 0 開始トリックを理解していることが前提。 |
| CASE + LEFT(読みやすい) | CASE WHEN CHARINDEX('-', Location)>0 THEN LEFT(Location, CHARINDEX('-',Location)-1) ELSE Location END | SQL に慣れていない人でも意味が把握しやすい。 多少コード量は増えるが、保守性が高い。 |
どちらを採用するかは、
- 一人で使うツール的なクエリ → SUBSTRING パターンで短く書く
- チームで運用するレポート・ストアド → CASE + LEFT で読みやすさ優先
といった観点で使い分けると良いでしょう。
Excelで同じ「ハイフン左側だけ抽出」を行う方法
Dayforce から CSV / Excel 出力したあとに、Excel 側で「拠点名だけ」を取り出したいケースも多いはずです。ここでは、Excel 365 以降と、それ以前の両方で使える方法を紹介します。
Excel 365 / Microsoft 365 の場合:TEXTBEFORE が最短
新しい Excel には TEXTBEFORE という非常に便利な関数が用意されています。Location がセル A2 に入っているとすると、次のように書くだけでハイフン左側を取得できます。
=TEXTBEFORE(A2, " - ")
引数は、
- 第1引数:元の文字列(Location 列)
- 第2引数:区切り文字(ここではスペースを含めた
" - ")
だけです。非常にシンプルで、SQL の CHARINDEX + LEFT に相当する処理を1関数で置き換えてくれます。
旧バージョンのExcelの場合:LEFT + FIND
古い Excel では TEXTBEFORE が使えないため、従来からの書き方で対応します。
=LEFT(A2, FIND(" - ", A2) - 1)
ここでも考え方は SQL と同じです。
FIND(" - ", A2)で「最初の ‘ – ‘ が何文字目か」を取得LEFT(A2, その位置 - 1)で左側だけを切り出す
ハイフンが含まれない行がある場合は、IFERROR と組み合わせると安全です。
=IFERROR(LEFT(A2, FIND(" - ", A2) - 1), A2)
このように書いておけば、
- ハイフンあり → 左側だけ取得
- ハイフンなし → 元の Location をそのまま返す
という動作になります。
SQL と Excel の対比
| 目的 | SQL Server(Dayforce) | Excel 365 以降 | 旧 Excel |
|---|---|---|---|
| Location のハイフン左側だけを取得 | COALESCE(NULLIF(SUBSTRING(Location, 0, CHARINDEX('-', Location)), ''), Location) | =TEXTBEFORE(A2, " - ") | =IFERROR(LEFT(A2, FIND(" - ", A2) - 1), A2) |
SQL と Excel の両方で同じ考え方を押さえておくと、どちらのツールでも迷わず実装できるようになります。
よくある勘違いと補足ポイント
LTRIM / RTRIM は「左右のどちらかを返す」関数ではない
ときどき見かける誤解として、
- LTRIM:文字列の「左側」を返す
- RTRIM:文字列の「右側」を返す
のように理解されているケースがありますが、どちらも違います。正しくは、
- LTRIM:先頭の空白文字(スペースなど)を取り除く
- RTRIM:末尾の空白文字を取り除く
という「トリミング」関数であり、今回のような「ハイフンを基準に左右を切り分ける」用途には直接関係ありません。
例えば、
SELECT
LTRIM(' Newport Plant'),
RTRIM('Newport Plant ');
は、いずれも文字列の中身は変えずに、前後の空白だけを削る処理です。Location 列から拠点名だけを取り出すには、やはり CHARINDEX や SUBSTRING / LEFT を使う必要があります。
#t というテーブル名の意味(テンポラリテーブル)
サンプルコードでよく見かける #t というテーブル名は、SQL Server の「一時テーブル」を表します。
#XXX:接続ごとに消えるローカル一時テーブル##XXX:複数接続から共有できるグローバル一時テーブル
この記事で使った #t も、あくまで解説用にサンプルデータを入れるためのものです。Dayforce の本番クエリでは、実際のテーブル名やビュー名に置き換えて使ってください。
Location にハイフンが複数含まれる場合
今回想定しているフォーマットは、
[拠点名] - [数字コード] - [補足情報]
のように、「最初のハイフンが拠点名とそれ以降を区切っている」形です。この前提が成り立つなら、最初のハイフンだけを見れば十分なので、CHARINDEX('-', Location) だけで問題ありません。
一方、もし何らかの事情で、
- 拠点名の中に
-を含む(例:Plant-A East - 10601 - L48) - 別のハイフンを基準に切り出したい
といったケースがあるなら、「どのハイフンを基準にするのか」を明確にしておく必要があります。
たとえば「2つ目のハイフンまでを拠点名として扱いたい」のであれば、CHARINDEX の開始位置をずらして 2回呼び出す、というテクニックが使えます。
-- 2つ目のハイフンの位置を求める例
DECLARE @loc nvarchar(100) = N'Plant-A East - 10601 - L48';
SELECT
CHARINDEX('-', @loc) AS FirstHyphenPos,
CHARINDEX('-', @loc, CHARINDEX('-', @loc) + 1) AS SecondHyphenPos;
この考え方を使えば、
- 最初のハイフン位置:
FirstHyphenPos - 2つ目のハイフン位置:
SecondHyphenPos
を基準にした文字列切り出しも実現できます。ただしクエリが複雑になるので、可能であれば元データのフォーマットを揃えておくほうが運用は楽です。
全角ハイフンや余計な空白が混ざっている場合の対策
実務のデータでは、
- 全角ハイフン(
-)と半角ハイフン(-)が混在している - 「 – 」の前後に余計な全角スペースがある
- 手入力のゆらぎで「–」「―」など別の記号が混じる
といったパターンも珍しくありません。このような場合、単純に CHARINDEX('-') だけに頼ると、「ハイフンが見つからない」扱いになってしまいます。
代表的な対策としては、先に「正規化」用の REPLACE を挟む方法があります。
SELECT
Location,
COALESCE(
NULLIF(
SUBSTRING(
-- 全角ハイフンを半角に揃える
REPLACE(Location, N'-', N'-'),
0,
CHARINDEX('-', REPLACE(Location, N'-', N'-'))
),
''
),
Location
) AS PlantName
FROM YourTable;
さらに、前後の余計な空白を消したい場合は、SQL Server 2017 以降であれば TRIM()、それ以前なら LTRIM(RTRIM(...)) を使うと良いでしょう。
TRIM(REPLACE(Location, N'-', N'-'))
このように、「まず文字を揃える」「そのうえでハイフン位置を基準に切り出す」という2段構えにしておくと、少々汚れたデータであっても安定して Location の左側だけを取得できます。
実務での活用例
拠点マスタと結合して人間が読めるレポートを作る
Location がコードと補足情報を含んだ長い文字列のままだと、レポートを見ても直感的に理解しづらいことがあります。そこで、事前に「拠点名だけ」を切り出して別名を付けておき、拠点マスタと結合してよりリッチな情報を出す、という使い方が便利です。
WITH LocationNormalized AS (
SELECT
e.EmployeeId,
e.Location,
COALESCE(
NULLIF(SUBSTRING(e.Location, 0, CHARINDEX('-', e.Location)), ''),
e.Location
) AS PlantName
FROM EmployeeSchedule e
)
SELECT
n.EmployeeId,
n.Location,
n.PlantName,
p.PlantCode,
p.PlantRegion
FROM LocationNormalized n
LEFT JOIN PlantMaster p
ON n.PlantName = p.PlantName;
このように、クエリの早い段階で Location を正規化しておくと、
- グルーピング(
GROUP BY PlantName) - 拠点別集計
- 別システムのマスタとの JOIN
などが綺麗に書けるようになります。
ビューや計算列として再利用しやすくしておく
毎回同じ SUBSTRING/LEFT ロジックを書くのは面倒なので、
- ビューに
PlantName列を追加しておく - 計算列としてテーブル定義自体に埋め込む
といった設計にしておくのも有効です。
CREATE VIEW v_EmployeeWithPlant AS
SELECT
e.*,
COALESCE(
NULLIF(SUBSTRING(e.Location, 0, CHARINDEX('-', e.Location)), ''),
e.Location
) AS PlantName
FROM EmployeeSchedule e;
このようなビューを1つ用意しておくだけで、あとはレポートや分析クエリ側から SELECT PlantName と書くだけでよくなり、「ハイフン左側だけを抽出するロジック」をどこからでも再利用できます。
まとめ:Locationの「ハイフン左側」はパターン化してしまおう
この記事では、Dayforce のような SQL Server 互換環境で Location 列からハイフン左側だけを取り出す方法を、SQL と Excel の両面から整理しました。
- 最短パターン:
COALESCE(NULLIF(SUBSTRING(Location, 0, CHARINDEX('-', Location)), ''), Location) - 読みやすいパターン:
CASE WHEN CHARINDEX('-', Location)>0 THEN LEFT(Location, CHARINDEX('-',Location)-1) ELSE Location END - Excel 365 以降:
=TEXTBEFORE(A2, " - ") - 旧Excel:
=IFERROR(LEFT(A2, FIND(" - ", A2) - 1), A2)
また、
- LTRIM / RTRIM は空白のトリミング専用であり、左右のどちらかを返す関数ではないこと
#tのような#付きテーブルは一時テーブルであり、サンプル用であれば本番コードに含める必要はないこと- 全角ハイフンや余計な空白が混じる現場データでは、先に
REPLACEやTRIMで正規化してから文字列操作を行うと安定すること
といった注意点も押さえておきました。
一度このパターンを身につけてしまえば、「コード – 数字 – 補足」のような文字列から必要な部分だけを取り出す処理はほとんどコピペで済むようになります。日々の Dayforce レポート作成や SQL Server での文字列加工の効率を上げるために、ぜひ自分用の「定番スニペット」として使い回してみてください。

コメント