1

誰かがすでにこのクエリで私を助けてくれましたが、私は適応を行い、問題が発生しました:

    SELECT 
        AVG(tyd.price) AS avg_price, COUNT(tyd.id_product) AS cnt, 
        tyd.id_marchand, tyd.id_product, 
        catalog.price AS c_price, tyd.price AS t_price, 
        tyd.amount AS t_am, pro_tyd.amount AS p_am, 
        pro_tyd.price AS p_price, catalog.img_src,  
        tyd.step, tyd.login AS tyd_l
    FROM catalog 
    INNER JOIN tyd ON catalog.id_marchand = tyd.id_marchand 
                   AND catalog.id_product =   tyd.id_product
                   AND tyd.step = "1" 
    INNER JOIN pro_tyd  ON tyd.id_marchand = pro_tyd.id_marchand 
                        AND tyd.id_product = pro_tyd.id_product
    GROUP BY 
         catalog.id_product, catalog.id_marchand
    HAVING 
         tyd.login = "user1@tyd.fr"

tyd.login = "user3@tyd.fr"どちらが下位IDである場合にのみ機能します。user1またはuser2では機能しません...理由がわかりません...!また、tyd.loginでグループ化すると機能しますが、この場合、AVGおよびCOUNT関数は1行でのみ機能します...

これが表です:

id  id_marchand  id_product   login       price  amount  delay  step    time   
29      1           1       user3@tyd.fr   344     1       0      1   1343297500
120     1           1       user1@tyd.fr   54      1       0      1   1343297504
109     1           1       user10@tyd.fr  34      1       0      1   1343298598

HAVING tyd.login = "user3@tyd.fr"それが完全に機能するとき。user1またはuser2の場合、0行になりました。

ご協力いただきありがとうございます

最初の件名:SQL、where条件をエスケープしながらグループの平均を取得

4

2 に答える 2

3

問題は、クエリが非決定的であるということです。グループ化する列によって追加の列が決定されない場合に、グループ化する列をさらに選択しています。後者が当てはまる場合、これはSQLのANSII標準に該当します。これは、(私の意見では)ステートメントの実行を許可するのはMySQLの失敗ではないためです。他のDBMSは逆の方向に進んでおり、特定の列がgroup byに含まれていない他の列の関数であるかどうかを判断できないため、groupbyに含まれていない選択リストの列を持つステートメントを許可するようになりました。

問題を単純化するために、次のデータセットを使用してください(表T)

ID    Col1    Col2
1     1       1
2     1       3

これを実行する:

SELECT Col1, MAX(Col2) AS MaxCol2, MIN(Col2) AS MinCol2, AVG(Col2) AS AvgCol2
FROM T
GROUP BY Col1

常に戻ってきます

Col1    MaxCol2    MinCol2    AvgCol2
1       3          1          2

IDただし、ミックスに投入した場合

SELECT ID, Col1, MAX(Col2) AS MaxCol2, MIN(Col2) AS MinCol2, AVG(Col2) AS AvgCol2
FROM T
GROUP BY Col1

1または2のどちらのIDが返されるかを決定する方法はありません。最も可能性の高い結果は、

ID    Col1    MaxCol2    MinCol2    AvgCol2
1    1       3          1          2

ただし、SQLには、結果が次のようになり得なかったことを示すものは何も定義されていません。

ID    Col1    MaxCol2    MinCol2    AvgCol2
2     1       3          1          2

したがって、上記が結果セットでありHAVING ID = 1、クエリに追加した場合、HAVING句がデータに適用される時点のため、結果は得られません。IDをに追加GROUP BYすると、2行になりますが、これは私が理解しているように、必要なものではなくWHERE、MIN、MAX、およびAVG関数に追加すると影響を受けます。したがって、サブクエリを使用する必要があります。したがって、この例では、

SELECT  T.ID, T.Col1, MaxCol2, MinCol2, AvgCol2
FROM    T
        INNER JOIN
        (   SELECT Col1, MAX(Col2) AS MaxCol2, MIN(Col2) AS MinCol2, AVG(Col2) AS AvgCol2
            FROM T
            GROUP BY Col1
        ) T2
            ON T.Col1 = T2.Col1
WHERE   ID = 1 -- OR ID = 2 DEPENDING ON REQUIREMENTS

これを状況に適用するために、データベースエンジンは、group byにない列に対して返される行は、ID = 29を含む行であると判断しました。したがって、HAVING句は、この行にのみ適用されます。 user1@tyd.frおよびuser10@tyd.frinは、HAVING句が適用されるまでに、結果からすでに削除されています。フィルタリングとは別に集計関数を実行する必要があります。

今、私はあなたのスキーマについて完全に頭を悩ませていませんが、非決定論的ステートメントの問題を十分に説明して、クエリを書き直す試みに必要な修正を加えることができることを願っています

SELECT  Avg_Price,
        Cnt,
        tyd.id_marchand, 
        tyd.id_product, 
        catalog.price AS c_price, 
        tyd.price AS t_price, 
        tyd.amount AS t_am, 
        pro_tyd.amount AS p_am, 
        pro_tyd.price AS p_price, 
        catalog.img_src,  
        tyd.step, 
        tyd.login AS tyd_l
FROM    Catalog
        INNER JOIN tyd
            ON catalog.id_marchand = tyd.id_marchand 
            AND catalog.id_product = tyd.id_product
        INNER JOIN Pro_tyd
            ON tyd.id_marchand = pro_tyd.id_marchand 
            AND tyd.id_product = pro_tyd.id_product
        INNER JOIN
        (   SELECT  ID_Marchand, ID_Product, Step, AVG(tyd.price) AS avg_price, COUNT(tyd.id_product) AS cnt
            FROM    Tyd
            WHERE   Step = '1'
            GROUP BY ID_Marchand, ID_Product, Step
        ) Agg
            ON Agg.id_marchand = pro_tyd.id_marchand 
            AND Agg.id_product = pro_tyd.id_product
            AND Agg.Step = tyd.Step
WHERE   tyd.Login = 'user1@tyd.fr'
于 2012-07-31T22:10:17.600 に答える
0

このクエリを追加したいだけです:

SELECT * FROM  tyd WHERE step = "1" 
GROUP BY tyd.id_product, tyd.id_marchand 
HAVING tyd.login = "user1@tyd.fr" 

同じ問題があります。tyd.login = "user3"の場合は機能しますが、他のユーザーが質問された場合は機能しません。

于 2012-07-31T18:25:58.580 に答える