1. ホーム
  2. sql

[解決済み] 最初の行への結合方法

2022-03-19 01:35:16

質問

具体的な、しかし仮定の例で説明します。

それぞれの 注文 は通常1つだけです。 ラインアイテム :

ご注文について

OrderGUID   OrderNumber
=========   ============
{FFB2...}   STL-7442-1      
{3EC6...}   MPT-9931-8A

LineItems。

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 を選ぶだけです。 となるため 十分 :

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, ...

そこで問題は、どちらをどうするかです。

  • 重複行の削除
  • 重複を避けるため、片方の行にのみ結合します。

最初の試み

最初の素朴な試みは、" にのみ参加することでした。 トップページ "ラインアイテム。

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' がありません。
テーブル名またはエイリアス名と一致する
はクエリで使用されます。

おそらく、内側のselectが外側のテーブルを見ないためだと思われます。

解決方法は?

SELECT   Orders.OrderNumber, LineItems.Quantity, LineItems.Description
FROM     Orders
JOIN     LineItems
ON       LineItems.LineItemGUID =
         (
         SELECT  TOP 1 LineItemGUID 
         FROM    LineItems
         WHERE   OrderID = Orders.OrderID
         )

SQL Server 2005 以降では、単に以下のように置き換えることができます。 INNER JOINCROSS APPLY :

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

ご注意ください TOP 1 がない場合 ORDER BY このクエリでは、1つの注文につき1つの行が取得されますが、それがどの行になるかは定義されていません。

クエリを複数回実行すると、同じ注文に対して異なる行が表示されることがありますが、これは基礎となる行が変更されていない場合です。

決定論的な順序が必要な場合は、その順序を決定するために ORDER BY 節を最内部のクエリに追加します。

sqlfiddleの例