JOIN
句を使用すると、この文の特定の属性間の関係に基づいて、複数の文や名前付き状態のレコードを結合できます。
SQL標準のサブセットに準拠するJOIN
句は、指定された結合条件で結合を行います。 結合条件は、FROM
文の属性を参照する任意のブール式である可能性があります。 式はカッコで囲む必要があります。
JOIN
句によって、常にFROM
句が変更されます。 2つの名前付きソース(名前付き状態のいずれかまたは両方)をFROM
句で指定できます。 フィールドは、単一表からの問合せを除き、取得元のソースを示すために考慮しなければなりません。
自己結合がサポートされています。 自己結合には文の別名が必要です。
どちらの入力表も、DEFINE
文またはRETURN
文(中間結果から)の結果である必要があります。
1つの文で、任意の数の結合を実行できます。
JOIN
の構文は、次のとおりです:
FROM <statement1> [alias] [INNER,CROSS,LEFT,RIGHT,FULL] JOIN <statement2> [alias] ON (Boolean-expression) [JOIN <statementN> [alias] ON (Boolean-expression)]*ここで、「文」は文または名前付きの状態です。 複数の
JOIN
句をFROM
句の下に配置できますが、いずれの文にも正確に1つのFROM
句が必要です。
結合のタイプ
EQLでは、次のタイプの結合がサポートされます:
INNER JOIN
では、左側と右側のレコードが結合され、結合条件によって結果レコードがフィルタ処理されます。 つまり、結合条件がTRUE
である行のみが含められます。 結合タイプを指定しない場合、JOIN
はデフォルトでINNER JOIN
に設定されます。 INNER
キーワードはJOIN
でのみ使用でき、EQLで他の結合タイプとともに使用するとエラーがスローされることに注意してください。
LEFT JOIN
、RIGHT JOIN
、およびFULL JOIN
(まとめて外部結合)は、他の結合条件に一致したレコードのない側からレコードでINNER JOIN
の結果を拡張します。 このような追加のレコードが一方の側に含まれる場合、結合結果のレコードには、他方の側のすべての属性のNULLが含まれます。 LEFT JOIN
には、左側からそのようなすべての行が含まれます。RIGHT JOIN
には、右側から該当するすべての行が含まれ、FULL JOIN
には、その反対側からのすべての行が含まれます。
CROSS JOIN
の結果は、左側と右側のデカルト積です。 各結果レコードには、対応する2つの側のレコードの両方からのアサイメントが含まれます。
正しく使用しないと、結合が使用可能なRAMを超えてDgraphが大きくなる可能性があるので注意してください。これは、非常に大きな結果が得られる可能性があるためです。 たとえば、100件のレコードがある結果のCROSS JOIN
および200件のレコードがある結果には20,000件のレコードが含まれます。 2つのベスト・プラクティスは、可能であればCROSS JOIN
を回避し、ON
条件に注意して、結果数が適切になるようにすることです。
INNER JOINの例
INNER JOIN
の例では、特定のサブカテゴリの売上がサブカテゴリ合計の10%を超える従業員が検出されます:
DEFINE EmployeeTotals AS SELECT ARB(DimEmployee_FullName) AS Name, SUM(FactSales_SalesAmount) AS Total FROM SaleState GROUP BY DimEmployee_EmployeeKey, ProductSubcategoryName; DEFINE SubcategoryTotals AS SELECT SUM(FactSales_SalesAmount) AS Total FROM SaleState GROUP BY ProductSubcategoryName; RETURN Stars AS SELECT EmployeeTotals.Name AS Name, EmployeeTotals.ProductSubcategoryName AS Subcategory, 100 * EmployeeTotals.Total / SubcategoryTotals.Total AS Pct FROM EmployeeTotals INNER JOIN SubcategoryTotals ON (EmployeeTotals.ProductSubcategoryName = SubcategoryTotals.ProductSubcategoryName) HAVING Pct > 10
自己結合の例
INNER JOIN
を使用した次の自己結合により、従業員ごとの累積日次売上合計が計算されます:
DEFINE Days AS SELECT FactSales_OrderDateKey AS DateKey, DimEmployee_EmployeeKey AS EmployeeKey, ARB(DimEmployee_FullName) AS EmployeeName, SUM(FactSales_SalesAmount) AS DailyTotal FROM SaleState GROUP BY DateKey, EmployeeKey; RETURN CumulativeDays AS SELECT SUM(PreviousDays.DailyTotal) AS CumulativeTotal, Day.DateKey AS DateKey, Day.EmployeeKey AS EmployeeKey, ARB(Day.EmployeeName) AS EmployeeName FROM Days Day JOIN Days PreviousDays ON (PreviousDays.DateKey <= Day.DateKey) GROUP BY DateKey, EmployeeKey
LEFT JOINの例
LEFT JOIN
の例では、円グラフで使用するために、上位5つのサブカテゴリをその他のバケットとともに計算します:
DEFINE Totals AS SELECT SUM(FactSales_SalesAmount) AS Total FROM SaleState GROUP BY ProductSubcategoryName; DEFINE Top5 AS SELECT ARB(Total) AS Total FROM Totals GROUP BY ProductSubcategoryName ORDER BY Total DESC PAGE(0,5); RETURN Chart AS SELECT COALESCE(Top5.ProductSubcategoryName, 'Other') AS Subcategory, SUM(Totals.Total) AS Total FROM Totals LEFT JOIN Top5 ON (Totals.ProductSubcategoryName = Top5.ProductSubcategoryName) GROUP BY Subcategory
LEFT JOIN
では、特定のリージョンの製品ごとにメトリックが計算され、そのリージョンで製品が販売されていなくても、すべての製品がリストに表示されます:
DEFINE Product AS SELECT ProductAlternateKey AS Key, ARB(ProductName) AS Name FROM SaleState GROUP BY Key; DEFINE RegionTrans AS SELECT ProductAlternateKey AS ProductKey, FactSales_SalesAmount AS Amount FROM SaleState WHERE DimSalesTerritory_SalesTerritoryRegion='United Kingdom'; RETURN Results AS SELECT Product.Key AS ProductKey, ARB(Product.Name) AS ProductName, COALESCE(SUM(RegionTrans.Amount), 0) AS SalesTotal, COUNT(RegionTrans.Amount) AS TransactionCount FROM Product LEFT JOIN RegionTrans ON (Product.Key = RegionTrans.ProductKey) GROUP BY ProductKey
FULL JOINの例
FULL JOIN
では、上位10製品の従業員販売合計の上位10件が計算され、各従業員と各製品が結果に表示されます:
DEFINE TopEmployees AS SELECT DimEmployee_EmployeeKey AS Key, ARB(DimEmployee_FullName) AS Name, SUM(FactSales_SalesAmount) AS SalesTotal FROM SaleState GROUP BY Key ORDER BY SalesTotal DESC PAGE (0,10); DEFINE TopProducts AS SELECT ProductAlternateKey AS Key, ARB(ProductName) AS Name, SUM(FactSales_SalesAmount) AS SalesTotal FROM SaleState GROUP BY Key ORDER BY SalesTotal DESC PAGE (0,10); DEFINE EmployeeProductTotals AS SELECT DimEmployee_EmployeeKey AS EmployeeKey, ProductAlternateKey AS ProductKey, SUM(FactSales_SalesAmount) AS SalesTotal FROM SaleState GROUP BY EmployeeKey, ProductKey HAVING [EmployeeKey] IN TopEmployees AND [ProductKey] IN TopProducts; RETURN Results AS SELECT TopEmployees.Key AS EmployeeKey, TopEmployees.Name AS EmployeeName, TopEmployees.SalesTotal AS EmployeeTotal, TopProducts.Key AS ProductKey, TopProducts.Name AS ProductName, TopProducts.SalesTotal AS ProductTotal, EmployeeProductTotals.SalesTotal AS EmployeeProductTotal FROM EmployeeProductTotals FULL JOIN TopEmployees ON (EmployeeProductTotals.EmployeeKey = TopEmployees.Key) FULL JOIN TopProducts ON (EmployeeProductTotals.ProductKey = TopProducts.Key)
CROSS JOINの例
CROSS JOIN
の例では、各製品サブカテゴリが表す売上合計の割合がわかります:
DEFINE GlobalTotal AS SELECT SUM(FactSales_SalesAmount) AS GlobalTotal FROM SaleState GROUP; DEFINE SubcategoryTotals AS SELECT SUM(FactSales_SalesAmount) AS SubcategoryTotal FROM SaleState GROUP BY ProductSubcategoryName; RETURN SubcategoryContributions AS SELECT SubcategoryTotals.ProductSubcategoryName AS Subcategory, SubcategoryTotals.SubcategoryTotal / GlobalTotal.GlobalTotal AS Contribution FROM SubcategoryTotals CROSS JOIN GlobalTotal