2012-07-31 32 views
1

有人已經幫我解決這個查詢,但我做了一個調整,我得到了一個問題:SQL有隻得到第一個記錄的行表,我想所有

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 = "[email protected]" 

tyd.login = "[email protected]"這是它只能較低的ID。不適用於user1或user2 ...我只是不明白爲什麼......!此外,它通過tyd.login但在這種情況下,AVG和COUNT函數只工作在一行中工作,如果我組...

下面是表:

id id_marchand id_product login  price amount delay step time 
29  1   1  [email protected] 344  1  0  1 1343297500 
120  1   1  [email protected] 54  1  0  1 1343297504 
109  1   1  [email protected] 34  1  0  1 1343298598 

HAVING tyd.login = "[email protected]"它完美的作品。當user1或user2我有0行。

感謝您的幫助

的第一個主題:Sql, get the average on a group while escaping the where condition

+1

您在濫用'HAVING',通常用於組過濾或聚合函數。我想你應該使用'WHERE tyd.login =「[email protected]」'。另外,您沒有「user1」,但是沒有「user10」。 – 2012-07-31 16:45:29

+0

如果我不使用having子句,則只會獲得userX行的AVG和COUNT。我希望每一行的AVG和COUNT都是相同的id_product和id_marchand。對不起,用戶1和10,我糾正它。 – pierreaurelemartin 2012-07-31 16:50:15

+0

你究竟想從這個查詢中得到什麼?和你是什麼意思**當HAVING tyd.login =「[email protected]」它完美的工作。**。你能解釋更多嗎? – hmmftg 2012-07-31 17:36:20

回答

3

問題是您的查詢是非確定性的。您正在選擇更多的列,按照您正在分組的列確定附加列的位置。如果後者是真的,那麼這將落入SQL的ANSII標準,因爲它不是(我認爲)MySQL的失敗,它允許聲明運行。其他DBMS的方式相反,因爲它們無法確定某些列是否不包含在組中的其他列的函數,現在它們將允許包含在列表中未包含在選擇列表中的列的任何語句。

爲了嘗試簡化問題採取以下數據集(表2)

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 

沒有確定哪個ID將被退回,1或2的方式,最有可能的結果是

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 

若要將此您的情況,數據庫引擎已deteremined,這將不會在GROUP BY返回的列行是包含ID = 29,所以排您的HAVING子句僅應用於此行,在您應用HAVING子句時,具有[email protected][email protected] in的行已經從結果中刪除。您需要分別對過濾執行聚合函數。

現在我還沒有完全得到我您的架構周圍的頭,但我希望我已經解釋了不確定性語句的問題非常好,你可以重寫你的查詢作出要求我嘗試任何ammendments

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 = '[email protected]' 
+0

我完全同意和理解你的解釋。我沒有嘗試你的解決方案,但我會和我不熟悉子查詢,所以它可以幫助我。但是,如果我按照你的帖子,問題應該是相同的查詢那裏(Marco):http://stackoverflow.com/questions/11740458/sql-get-the-average-on-a-group-while-escaping在哪裏條件,但我得到了所有的線,而不僅僅是第一個。在那個查詢中,has對一行沒有選擇性。但可能它並不完全一樣。我會盡快看。非常感謝你的幫助。 – pierreaurelemartin 2012-08-01 10:25:02

+0

所以你給我的查詢完全正常。但是真的,我不明白爲什麼它使用step =「0」而不是step =「1」。你認爲我必須重寫第一個查詢嗎? – pierreaurelemartin 2012-08-01 12:28:30

+0

我已經用可能的解決方案更新了答案。我仍然不確定你究竟是什麼,或者平均值應該是多少,或者應該如何分組。但希望新的查詢能讓你朝正確的方向發展。 – GarethD 2012-08-01 12:48:21

0

我只是想補充一點,這個查詢:

SELECT * FROM tyd WHERE step = "1" 
GROUP BY tyd.id_product, tyd.id_marchand 
HAVING tyd.login = "[email protected]" 

有同樣的問題。當tyd.login =「user3」時工作,但當其他用戶被詢問時不工作...

+0

還是不明白! – hmmftg 2012-07-31 18:30:01

+0

如果你在第一篇文章中拿我的表,我得到這一行:120/1/1/[email protected]/432(354 + 44 + 34/3)/ 3(1 + 1 + 1)/ 1/time ...當我把HAVING登錄= user3和零線時,登錄= user1 – pierreaurelemartin 2012-07-31 18:45:01

相關問題