2

私はしばらくの間これを修正しようとしていて、本当に小さな問題で立ち往生しているので、誰かが助けてくれることを願っています.

以下のクエリでは、主に次のことをしようとしています。

注文からすべてのストック コードを選択します。

次に、各証券コードが STOCK_LOCATIONS テーブルに格納されているすべての場所を検索します。

次に、STOCK_LOCATIONS テーブルから 1 つの場所を返します。

ただし、LOCATION_DATA テーブルを相互参照する必要があります。LOCATION_DATA テーブルの各場所には PICK という列があり、Y または N のいずれかが含まれています。最初の選択肢として Y を含む場所を返し、PICK 列に Y が存在しない場合は N を返したいと思います。

内部結合 LOCATION_DATA クエリで結果を並べ替える必要がありますが、これは不可能です。INNER JOIN 内に SELECT ステートメントを追加しようとしましたが (これがおそらく正しい方法だと思います)、うまくいきませんでした。

アドバイスをいただければ幸いです。よろしくお願いします...

SELECT
    STOCK_LOCATIONS.*,
    LOCATION_DATA.*,
    STOCK_DATA.PHYSICAL,
    ORDER_DATA.ENTRY,
    ORDER_DATA.STOCK,
    ORDER_DATA.ORDER_QTY,
    (SELECT
        COUNT(STOCK_LOCATIONS.location)
        FROM STOCK_LOCATIONS 
        WHERE ORDER_DATA.STOCK = STOCK_LOCATIONS.sku
        GROUP BY STOCK_LOCATIONS.sku
        HAVING COUNT(STOCK_LOCATIONS.sku) > 1
    ) AS RowCount
FROM ORDER_DATA
INNER JOIN STOCK_DATA
    ON ORDER_DATA.STOCK = STOCK_DATA.STOCK_CODE             
INNER JOIN STOCK_LOCATIONS
    ON ORDER_DATA.STOCK = STOCK_LOCATIONS.sku
INNER JOIN LOCATION_DATA
    ON STOCK_LOCATIONS.location = LOCATION_DATA.location
WHERE ORDER_DATA.ORDER_REF = '21254'    
GROUP BY ORDER_DATA.STOCK
ORDER BY LOCATION_DATA.pick_order ASC

ここにいくつかのサンプルデータがあります

そして、望ましい出力の例

STOCK_LOCATIONS     
sku         location    
123456      A1  
123457      A2  
123459      C1  
123456      B1  
123457      B2  


LOCATION_DATA       
location    pick    
A1          Y   
A2          Y   
B1          N   
B2          N   
C1          N   


STOCK_DATA      
STOCK_CODE  PHYSICAL    
123456      10  
123457      0   
123459      100 


ORDER_DATA      
ENTRY   STOCK       ORDER_QTY
1       123456      10
2       123457      2
3       123459      1


RETURN DATA     
STOCK_CODE  ENTRY   LOCATION    PICK    ORDER_QTY   PHYSICAL    
123456      1       A1          Y       10          10
123457      2       A2          Y       2           0
123459      3       C1          N       1           100

不明なテーブルに関連するエラーをスローする更新された試行は次のとおりです。

// OPTION 1

SELECT
    STOCK_LOCATIONS.*,
    LOCATION_DATA.*,
    STOCK_DATA.PHYSICAL,
    ORDER_DATA.ENTRY,
    ORDER_DATA.STOCK,
    ORDER_DATA.ORDER_QTY,
    (SELECT
        COUNT(STOCK_LOCATIONS.location)
        FROM STOCK_LOCATIONS 
        WHERE ORDER_DATA.STOCK = STOCK_LOCATIONS.sku
        GROUP BY STOCK_LOCATIONS.sku
        HAVING COUNT(STOCK_LOCATIONS.sku) > 1
    ) AS RowCount,
    (SELECT 
        CASE
            WHEN dat1.pick IS NOT NULL THEN loc1.location
            ELSE loc2.location 
        END
    ) AS location

FROM ORDER_DATA
INNER JOIN STOCK_DATA
    ON ORDER_DATA.STOCK = STOCK_DATA.STOCK_CODE

LEFT JOIN STOCK_LOCATIONS loc1
    ON ORDER_DATA.STOCK = loc1.sku

LEFT JOIN LOCATION_DATA dat1
    ON loc1.location = dat1.location
    AND dat1.pick = 'Y'

LEFT JOIN STOCK_LOCATIONS loc2
    ON ORDER_DATA.STOCK = loc2.sku

LEFT JOIN STOCK_LOCATIONS dat2
    ON loc2.location = dat2.location
    AND dat1.pick = 'N'

WHERE ORDER_DATA.ORDER_REF = '".$_GET_q."'  
GROUP BY ORDER_DATA.STOCK
ORDER BY LOCATION_DATA.pick_order ASC

// OPTION 2

SELECT
    STOCK_LOCATIONS.*,
    LOCATION_DATA.*,
    STOCK_DATA.PHYSICAL,
    ORDER_DATA.ENTRY,
    ORDER_DATA.STOCK,
    ORDER_DATA.ORDER_QTY,
    (SELECT
        COUNT(STOCK_LOCATIONS.location)
        FROM STOCK_LOCATIONS 
        WHERE ORDER_DATA.STOCK = STOCK_LOCATIONS.sku
        GROUP BY STOCK_LOCATIONS.sku
        HAVING COUNT(STOCK_LOCATIONS.sku) > 1
    ) AS RowCount

FROM ORDER_DATA
INNER JOIN STOCK_DATA
    ON ORDER_DATA.STOCK = STOCK_DATA.STOCK_CODE

JOIN STOCK_LOCATIONS loc1
    ON ORDER_DATA.STOCK = loc1.sku

JOIN LOCATION_DATA dat1
    ON loc1.location = dat1.location 
    AND dat1.pick = CASE WHEN EXISTS
    (SELECT
        *
        FROM STOCK_LOCATIONS loc2
        JOIN LOCATION_DATA dat2
            ON loc2.location = dat2.location
            AND dat1.pick = 'Y'
        WHERE ORDER_DATA.STOCK = loc2.sku
    )
    THEN 'Y' ELSE 'N' END

WHERE ORDER_DATA.ORDER_REF = '".$_GET_q."'  
GROUP BY ORDER_DATA.STOCK
ORDER BY LOCATION_DATA.pick_order ASC

// OPTION 3

SELECT
    STOCK_LOCATIONS.*,
    LOCATION_DATA.*,
    STOCK_DATA.PHYSICAL,
    ORDER_DATA.ENTRY,
    ORDER_DATA.STOCK,
    ORDER_DATA.ORDER_QTY,

    (SELECT
        COUNT(STOCK_LOCATIONS.location)
        FROM STOCK_LOCATIONS 
        WHERE ORDER_DATA.STOCK = STOCK_LOCATIONS.sku
        GROUP BY STOCK_LOCATIONS.sku
        HAVING COUNT(STOCK_LOCATIONS.sku) > 1
    ) AS RowCount,

    (SELECT 
            STOCK_LOCATIONS.location
            FROM STOCK_LOCATIONS 
            INNER JOIN LOCATION_DATA
                ON STOCK_LOCATIONS.location = LOCATION_DATA.location
            WHERE ORDER_DATA.STOCK = STOCK_LOCATIONS.sku
            ORDER BY pick DESC, rand()
            LIMIT 1
    ) AS location

FROM ORDER_DATA

INNER JOIN STOCK_DATA
    ON ORDER_DATA.STOCK = STOCK_DATA.STOCK_CODE             

INNER JOIN STOCK_LOCATIONS
    ON ORDER_DATA.STOCK = STOCK_LOCATIONS.sku

INNER JOIN LOCATION_DATA
    ON STOCK_LOCATIONS.location = LOCATION_DATA.location

WHERE ORDER_DATA.ORDER_REF = '".$_GET_q."'  
GROUP BY ORDER_DATA.STOCK
ORDER BY LOCATION_DATA.pick_order ASC   
4

2 に答える 2

0

select句のサブクエリとしてこれを行うことができると思います:

SELECT STOCK_LOCATIONS.*, LOCATION_DATA.*, STOCK_DATA.PHYSICAL,
       ORDER_DATA.ENTRY, ORDER_DATA.STOCK, ORDER_DATA.ORDER_QTY, 
       (SELECT COUNT(STOCK_LOCATIONS.location) 
        FROM STOCK_LOCATIONS  
        WHERE ORDER_DATA.STOCK = STOCK_LOCATIONS.sku   
        GROUP BY STOCK_LOCATIONS.sku  
        HAVING COUNT(STOCK_LOCATIONS.sku) > 1
       ) AS RowCount,
       (SELECT STOCK_LOCATIONS.location
        FROM STOCK_LOCATIONS  
        WHERE ORDER_DATA.STOCK = STOCK_LOCATIONS.sku
        order by pick desc, rand()
        limit 1
       ) AS ChosenLocation

これは、1 つの行を選択する相関サブクエリを実行します。必要なビジネス ロジックに適合するように命令します。場所に関する詳細情報が必要な場合は、これをサブクエリに入れて、追加情報に参加します。

于 2012-08-13T13:34:15.820 に答える
0

pick = 'Y'ロケーション テーブルを2 回結合できますpick = 'N'。次に、case ステートメントを使用して最初のステートメントを優先し、2 番目のステートメントにフォールバックすることができます。

SELECT  case
        when dat1.pick is not null then loc1.location
        else loc2.location 
        end as Location
....
LEFT JOIN 
        STOCK_LOCATIONS loc1
ON      ORDER_DATA.STOCK = loc1.sku
LEFT JOIN
        LOCATION_DATA dat1
ON      loc1.location = dat1.location
        AND dat1.pick = 'Y'
LEFT JOIN
        STOCK_LOCATIONS loc2
ON      ORDER_DATA.STOCK = loc2.sku
LEFT JOIN
        LOCATION_DATA dat2
ON      loc2.location = dat2.location
        AND dat1.pick = 'N'

もう 1 つのオプションは、サブクエリを使用した結合条件です。pick = 'Y'サブクエリは、存在する場合は場所を探し、そうでない場合はフォールバックできpick = 'N'ます。

JOIN    STOCK_LOCATIONS loc1
ON      ORDER_DATA.STOCK = loc1.sku
JOIN    LOCATION_DATA dat1
ON      loc1.location = dat1.location 
        AND dat1.pick = case when exists
        (
        select  *
        from    STOCK_LOCATIONS loc2
        JOIN    LOCATION_DATA dat2
        ON      loc2.location = dat2.location
                AND dat1.pick = 'Y'
        WHERE   ORDER_DATA.STOCK = loc2.sku
        )
        then 'Y' else 'N' end
于 2012-08-13T10:34:44.033 に答える