T-SQL GROUP BY:他のグループ化された列を含める最良の方法
-
06-07-2019 - |
質問
私は、MS SQL Serverに何かを移植しようとしているMySQLユーザーです。
いくつかのテーブルを結合し、GROUP BYを介していくつかの列を集約しています。
単純な例は従業員とプロジェクトです:
select empID, fname, lname, title, dept, count(projectID)
from employees E left join projects P on E.empID = P.projLeader
group by empID
...これはMySQLで機能しますが、MS SQLはより厳密であり、すべてが集約関数で囲まれているか、GROUP BY句の一部である必要があります。
したがって、もちろん、この単純な例では、group by句に追加の列を含めることができると仮定しています。しかし、私が扱っている実際のクエリはかなり複雑であり、いくつかの非集約列で実行される一連の操作が含まれています。つまり、group by句にそれらのすべてを含めるのは本当にいでしょう。
これを行うより良い方法はありますか?
解決
これらの行の周りで何かを動作させることができます:
select e.empID, fname, lname, title, dept, projectIDCount
from
(
select empID, count(projectID) as projectIDCount
from employees E left join projects P on E.empID = P.projLeader
group by empID
) idList
inner join employees e on idList.empID = e.empID
これにより、余分なグループごとの操作を回避し、必要なデータを取得できます。また、いくつかのシナリオ(完全な情報を返さない場合)でインデックスを適切に使用する可能性が高く、ページングとの組み合わせを改善できます。
他のヒント
" group by句にそれらのすべてを含めると、本当にいものになります。"
はい-それが唯一の方法です*-集約されていない列をコピーしてgroup by句に貼り付け、エイリアスを削除するだけです...
*ネストされたSELECTでラップすることもできますが、それはおそらくasいことです...
MySQLは珍しく、技術的にはSQL標準に準拠していませんが、GROUP BY句から項目を省略できます。標準SQLでは、select-listの各非集計列は、GROUP BY句に完全にリストする必要があります(名前または序数のいずれかですが、非推奨です)。
(ああ、MySQLは珍しいですが、省略表記ができるのはいいことです。)
従業員からのempIDに基づいてグループを作成する必要がないため、サブクエリに参加する必要はありません-プロジェクトのprojectLeaderフィールドで実行できます。
内部結合(私が言うように)を使用すると、少なくとも1つのプロジェクトを持つ従業員のリストを取得できます。すべての従業員のリストが必要な場合は、左結合に変更するだけです
select e.empID, e.fname, e.lname, e.title, e.dept, p.projectIDCount
from employees e
inner join ( select projLeader, count(*) as projectIDCount
from projects
group by projLeader
) p on p.projLeader = e.empID
select句のサブクエリも適切な場合があります。指定された例では機能しますが、実際に処理している複雑なクエリでは機能しない場合があります。
select
e.empID, fname, lname, title, dept
, (select count(*) from projects p where p.projLeader = e.empId) as projectCount
from
from employees E