具体的ではあるが仮説的な例を挙げてみます。
通常、各注文には 1 つの明細項目のみが含まれます。
注文:
OrderGUID OrderNumber
========= ============
{FFB2...} STL-7442-1
{3EC6...} MPT-9931-8A
明細項目:
LineItemGUID Order ID Quantity Description
============ ======== ======== =================================
{098FBE3...} 1 7 prefabulated amulite
{1609B09...} 2 32 spurving bearing
しかし、まれに 2 つの明細項目を含む注文がある場合があります。
LineItemID Order ID Quantity Description
========== ======== ======== =================================
{A58A1...} 6,784,329 5 pentametric fan
{0E9BC...} 6,784,329 5 differential girdlespring
通常、ユーザーに注文を表示するときは次のようになります。
SELECT Orders.OrderNumber, LineItems.Quantity, LineItems.Description
FROM Orders
INNER JOIN LineItems
ON Orders.OrderID = LineItems.OrderID
注文の単一のアイテムを表示したいのですが、2 つ (またはそれ以上) のアイテムを含む注文が時々あるため、注文が重複しているように見えます。
OrderNumber Quantity Description
=========== ======== ====================
STL-7442-1 7 prefabulated amulite
MPT-9931-8A 32 spurving bearing
KSG-0619-81 5 panametric fan
KSG-0619-81 5 differential girdlespring
私が本当に望んでいるのは、SQL Server が1 つだけ選択できるようにすることです。これで十分です。
OrderNumber Quantity Description
=========== ======== ====================
STL-7442-1 7 prefabulated amulite
MPT-9931-8A 32 differential girdlespring
KSG-0619-81 5 panametric fan
冒険したい場合は、複数あることを示す省略記号をユーザーに表示するかもしれません。
OrderNumber Quantity Description
=========== ======== ====================
STL-7442-1 7 prefabulated amulite
MPT-9931-8A 32 differential girdlespring
KSG-0619-81 5 panametric fan, ...
そこで問題となるのは、
- 「重複」行を削除する
- 重複を避けるために、行の1つだけに結合します。
最初の試み
私の最初の素朴な試みは、「 TOP 1 」の行項目のみに結合することでした。
SELECT Orders.OrderNumber, LineItems.Quantity, LineItems.Description
FROM Orders
INNER JOIN (
SELECT TOP 1 LineItems.Quantity, LineItems.Description
FROM LineItems
WHERE LineItems.OrderID = Orders.OrderID) LineItems2
ON 1=1
しかし、次のようなエラーが発生します:
列またはプレフィックス「Orders」が、クエリで使用されている
テーブル名またはエイリアス名と一致しません。
おそらく、内部選択では外部テーブルが参照されないためです。
ベストアンサー1
SELECT Orders.OrderNumber, LineItems2.Quantity, LineItems2.Description
FROM Orders
CROSS APPLY
(
SELECT TOP 1 LineItems.Quantity, LineItems.Description
FROM LineItems
WHERE LineItems.OrderID = Orders.OrderID
) LineItems2
INNER JOIN
2005 より前のバージョンの SQL Server では、の代わりにを使用する必要がありますCROSS APPLY
。
SELECT Orders.OrderNumber, LineItems.Quantity, LineItems.Description
FROM Orders
JOIN LineItems
ON LineItems.LineItemGUID =
(
SELECT TOP 1 LineItemGUID
FROM LineItems
WHERE OrderID = Orders.OrderID
)
TOP 1
without は決定論的ではないことに注意してくださいORDER BY
。このクエリでは、注文ごとに 1 つの明細項目が取得されますが、どの明細項目になるかは定義されません。
クエリを複数回呼び出すと、基礎となるものが変更されていなくても、同じ注文に対して異なる明細項目が返されることがあります。
決定論的な順序が必要な場合は、ORDER BY
最も内側のクエリに句を追加する必要があります。