以下に示すSQLクエリがあります。like
演算子を使用して複数の値を選択します。
私のクエリは正しいですか?
SELECT top 1 employee_id, employee_ident, utc_dt, rx_dt
FROM employee
INNER JOIN employee_mdata_history
ON employee.ident=employee_mdata_history.employee_ident
WHERE employee_id like 'emp1%' , 'emp3%'
ORDER BY rx_dt desc
そうでない場合、誰かが私を修正できますか?
テーブルに'emp1'
と'emp3'
で始まる大量のデータがあります。 rx_dt
に基づいて、上位3つの「emp1」と上位2つの「emp3」で結果をフィルタリングできますか?
または、次の方法を試すこともできます。
SELECT
x.*
FROM
(
VALUES
('emp1%', 3),
('emp3%', 2)
) AS v (pattern, row_count)
CROSS APPLY
( -- your query
SELECT top (v.row_count)
employee_id, employee_ident, utc_dt, rx_dt
FROM employee
INNER JOIN employee_mdata_history
ON employee.ident=employee_mdata_history.employee_ident
WHERE employee_id like v.pattern
ORDER BY rx_dt desc
) AS x
;
VALUES
行コンストラクターは、パターンリストをテーブルとして表し、各パターンに、そのパターンで取得する行数を追加で提供します。 CROSS APPLY演算子は、クエリをパターンリストのすべての行、つまりすべてのパターンに適用し、各パターンの行数をパターンリストの対応する値に制限します。
ちなみに、この機会に、2つ以上のテーブルから読み取るクエリでは、常にテーブルエイリアスで列を修飾することをお勧めします。これにより、クエリが読みやすくなり、理解しやすくなります。長いエイリアスを繰り返し使用しないように、常に短いエイリアスを使用できます。例えば:
SELECT TOP (1)
e.employee_id,
h.employee_ident,
...
FROM
dbo.employee AS e
INNER JOIN dbo.employee_mdata_history AS h
ON e.ident = h.employee_ident
WHERE
e.employee_id LIKE ...
ORDER BY
...
OR/AND条件を使用する必要があります。
SELECT TOP (1)
employee_id, employee_ident, utc_dt, rx_dt
FROM employee
INNER JOIN employee_mdata_history
ON employee.ident = employee_mdata_history.employee_ident
WHERE employee_id like 'emp1%'
OR employee_id like 'emp3%'
ORDER BY rx_dt desc;
MS-Docsの OR(Transact-SQL) をご覧ください。
私は例を設定しました:
create table employees(employee_id varchar(10), employee_name varchar(100)); insert into employees values ('emp10', 'Bryan Nelson'), ('emp12', 'Rosalyn Sanders'), ('emp13', 'Rose Tudler'), ('emp20', 'Julio Gomez'), ('emp30', 'Ian McGregor'), ('emp40', 'Anne Hatt'); GO
SELECT employee_id, employee_name FROM employees WHERE employee_id LIKE 'emp1%' OR employee_id LIKE 'emp3%'; GO
employee_id |従業員名 :------- :-------------- emp10 |ブライアンネルソン emp12 |ロザリン・サンダース emp13 |ローズタドラー emp30 |イアン・マクレガー
TOP 1を使用していることに注意してください。使用する条件の数に関係なく、最大で1行を取得します。
SELECT TOP 1 employee_id, employee_name FROM employees WHERE employee_id LIKE 'emp1%' OR employee_id LIKE 'emp3%'; GO
employee_id |従業員名 :---------- | :------------ emp10 |ブライアンネルソン
TOP(X)行が必要な場合WHERE employee_id LIKE 'emp1%'
プラスTOP(X)行WHERE employee_id LIKE 'emp3%'
UNION ALLで結合された2つの選択ステートメントを使用できます。
SELECT TOP 3 employee_id, employee_name FROM employees WHERE employee_id LIKE 'emp1%' UNION ALL SELECT TOP 1 employee_id, employee_name FROM employees WHERE employee_id LIKE 'emp3%' GO
employee_id |従業員名 :---------- | :-------------- emp10 |ブライアンネルソン emp12 |ロザリン・サンダース emp13 |ローズタドラー emp30 |イアン・マクレガー
さらに、パターン検索を追加しますが、このソリューションはパターンに一致するすべてのレコードを返します。LIKE 'emp [13]%'
SELECT employee_id, employee_name FROM employees WHERE employee_id LIKE 'emp[13]%' GO
employee_id |従業員名 :---------- | :-------------- emp10 |ブライアンネルソン emp12 |ロザリン・サンダース emp13 |ローズタドラー emp30 |イアン・マクレガー
dbfiddle ---(ここ
1行where employee_id like 'emp1%'
と別のwhere employee_id like 'emp3%'
が必要だと思います。これを実現する1つの方法は、union
を使用することです。
SELECT t1.*
FROM
( SELECT top 1 employee_id, employee_ident, utc_dt, rx_dt
FROM employee
JOIN employee_mdata_history
ON employee.ident=employee_mdata_history.employee_ident
WHERE employee_id like 'emp1%'
ORDER BY rx_dt desc
) AS t1
UNION ALL
SELECT t2.*
FROM
( SELECT top 1 employee_id, employee_ident, utc_dt, rx_dt
FROM employee
JOIN employee_mdata_history
ON employee.ident=employee_mdata_history.employee_ident
WHERE employee_id like 'emp3%'
ORDER BY rx_dt desc
) AS t2 ;
ユニオンのレッグは互いに素であることが保証されているため、UNION ALL
を使用できます。これは、UNION
だけを使用する場合と比較して、パフォーマンス上の利点になる場合があります。
SQL Server 2008はrow_number()のようなウィンドウ関数をサポートしているので、次のようなものを使用できます。
SELECT employee_id, employee_ident, utc_dt, rx_dt
FROM (
SELECT employee_id, employee_ident, utc_dt, rx_dt
, row_number() over (partition by substring(employee_id,1,4)
order by rx_dt desc) as rn
FROM employee
JOIN employee_mdata_history
ON employee.ident = employee_mdata_history.employee_ident
WHERE employee_id like 'emp1%'
OR employee_id like 'emp3%'
) as T
WHERE rn = 1
ORDER BY rx_dt desc;