サーチ…
前書き
優れた読みやすいSQLクエリの作成方法と優れた実践例
キーワードと名前の書式設定とスペル
テーブル/カラム名
フォーマットテーブル/カラム名の2つの一般的な方法があるCamelCase
とsnake_case
:
SELECT FirstName, LastName
FROM Employees
WHERE Salary > 500;
SELECT first_name, last_name
FROM employees
WHERE salary > 500;
名前は、オブジェクトに格納されているものを記述する必要があります。これは、列名が通常は特異でなければならないことを意味します。テーブル名が単数形か複数形かを問わなければならないかどうかは、よく議論されている質問ですが、実際には複数のテーブル名を使用する方が一般的です。
tbl
やcol
ような接頭辞や接尾辞を追加すると可読性が低下するため、避けてください。ただし、SQLキーワードとの競合を避けるために使用されることがあります。通常は、トリガーやインデックス(通常は名前はクエリでは記述されません)で使用されます。
キーワード
SQLキーワードは大文字と小文字を区別しません。ただし、大文字で記述するのが一般的です。
SELECT *
SELECT *
は、表内で定義されているのと同じ順序ですべての列を戻します。
SELECT *
を使用すると、クエリによって返されるデータは、テーブル定義が変更されるたびに変更される可能性があります。これにより、異なるバージョンのアプリケーションまたはデータベースが互いに互換性がないというリスクが増加します。
さらに、必要以上に多くの列を読み取ると、ディスクとネットワークI / Oの量が増える可能性があります。
したがって、実際に取得する列を常に明示的に指定する必要があります。
--SELECT * don't
SELECT ID, FName, LName, PhoneNumber -- do
FROM Emplopees;
(インタラクティブクエリを実行する場合、これらの考慮事項は適用されません)。
ただし、EXISTSは実際のデータを無視します(少なくとも1つの行が見つかった場合にのみチェックします)ので、 SELECT *
はEXISTS演算子のサブクエリで問題にはなりません。同じ理由で、EXISTSの特定の列を列挙することは意味がありません。したがって、 SELECT *
実際に意味があります。
-- list departments where nobody was hired recently
SELECT ID,
Name
FROM Departments
WHERE NOT EXISTS (SELECT *
FROM Employees
WHERE DepartmentID = Departments.ID
AND HireDate >= '2015-01-01');
インデント
広く受け入れられている基準はありません。誰もが認めていることは、すべてを1行に絞ることが悪いことです。
SELECT d.Name, COUNT(*) AS Employees FROM Departments AS d JOIN Employees AS e ON d.ID = e.DepartmentID WHERE d.Name != 'HR' HAVING COUNT(*) > 10 ORDER BY COUNT(*) DESC;
少なくとも、すべての句を新しい行に入れ、そうでなければ長すぎるようにするならば、行を分割する:
SELECT d.Name,
COUNT(*) AS Employees
FROM Departments AS d
JOIN Employees AS e ON d.ID = e.DepartmentID
WHERE d.Name != 'HR'
HAVING COUNT(*) > 10
ORDER BY COUNT(*) DESC;
時には、節を導入するSQLキーワードの後のすべてが同じ列に字下げされます。
SELECT d.Name,
COUNT(*) AS Employees
FROM Departments AS d
JOIN Employees AS e ON d.ID = e.DepartmentID
WHERE d.Name != 'HR'
HAVING COUNT(*) > 10
ORDER BY COUNT(*) DESC;
(これは、SQLキーワードを整列させながら行うこともできます)。
別の一般的なスタイルは、重要なキーワードを独自の行に追加することです。
SELECT
d.Name,
COUNT(*) AS Employees
FROM
Departments AS d
JOIN
Employees AS e
ON d.ID = e.DepartmentID
WHERE
d.Name != 'HR'
HAVING
COUNT(*) > 10
ORDER BY
COUNT(*) DESC;
類似した複数の式を垂直に整列させると、読みやすさが向上します。
SELECT Model,
EmployeeID
FROM Cars
WHERE CustomerID = 42
AND Status = 'READY';
複数の行を使用すると、SQLコマンドを他のプログラミング言語に埋め込むことが難しくなります。しかし、多くの言語では、C#の@"..."
"""..."""
、Pythonの"""..."""
R"(...)"
、C ++のR"(...)"
、複数行の文字列の仕組みがあります。
結合
明示的な結合は常に使用する必要があります。 暗黙的な結合にはいくつかの問題があります。
結合条件はWHERE節のどこかにあり、他のフィルタ条件と混在しています。これにより、どのテーブルが結合されているか、どのように結合されているかがわかりにくくなります。
上記のため、間違いのリスクが高くなり、後で見つかる可能性が高くなります。
標準SQLでは、明示的な結合だけで外部結合を使用できます 。
SELECT d.Name, e.Fname || e.LName AS EmpName FROM Departments AS d LEFT JOIN Employees AS e ON d.ID = e.DepartmentID;
明示的な結合では、USING句を使用できます。
SELECT RecipeID, Recipes.Name, COUNT(*) AS NumberOfIngredients FROM Recipes LEFT JOIN Ingredients USING (RecipeID);
(これにより、両方のテーブルが同じ列名を使用する必要があります。
USINGは結果から重複した列を自動的に削除します。たとえば、このクエリの結合は単一のRecipeID
列を返します。