簡體   English   中英

SQL“GROUP BY”問題

[英]SQL “GROUP BY” issue

我正在設計一個購物車。 為了避免在產品價格發生變化后顯示不准確定價的舊發票問題,我將價格字段從Product表移動到ProductPrice表中,該表包含3個字段,pid,日期和價格。 pid和date構成表的主鍵。 這是表格的示例:

pid    date     price
1      1/1/09   50
1      2/1/09   55
1      3/1/09   54

使用SELECTGROUP BY查找每個產品的最新價格,我提出:

SELECT pid, price, max(date) FROM ProductPrice GROUP BY pid

返回的日期和pid是准確的。 我收到的每個獨特的pid只有1個條目,隨之而來的日期是該pid的最新日期。 然而,令人驚訝的是價格回歸。 它返回了匹配pid的第一行的價格,在這種情況下是50。

在重述我的陳述之后,我想出了這個:

SELECT pp.pid, pp.price, pp.date FROM ProductPrice AS pp
INNER JOIN (
    SELECT pid AS lastPid, max(date) AS lastDate FROM ProductPrice GROUP BY pid
) AS m
ON pp.pid = lastPid AND pp.date = lastDate

雖然重寫的語句現在產生了正確的價格(54),但這樣一個簡單的聲音查詢需要內部聯接才能執行似乎令人難以置信。 我的問題是,我的第二個陳述是完成我需要做的最簡單的方法嗎? 或者我在這里遺漏了什么? 提前致謝!

詹姆士

您獲得任意價格的原因是,如果您使用GROUP BY ,mysql無法知道要選擇哪些列。 它知道它需要一個價格和每個pid 日期,並且可以按照你的請求獲取最新日期max(date)但是選擇返回一個對他來說最有效的價格 - 你沒有為它提供一個聚合函數列(實際上,您的第一個查詢不是有效的SQL。)

您的第二個查詢看起來沒問題,但這里有一個更短的選擇:

SELECT pid, price, date
FROM ProductPrice p
WHERE date = (SELECT MAX(date) FROM ProductPrice tmp WHERE tmp.pid = p.pid)

但是,如果您經常訪問最新價格(我認為您這樣做),我建議您將舊列添加回原始表以保留最新值,如果您可以選擇再次更改數據庫結構。

我認為你打破了數據庫架構。

為了避免在產品價格發生變化后顯示不准確定價的舊發票問題,我將價格字段從Product表移動到ProductPrice表中,該表包含3個字段,pid,日期和價格。 pid和date構成表的主鍵。

正如您所指出的,您需要保留價格的變化歷史記錄。 但除了新表之外,您仍然可以將當前價格保留在products表中。 這將使您的生活更輕松(並且您的查詢更快)。

你可能想試試這個:

SELECT pid, price, date FROM ProductPrice GROUP BY pid ORDER BY date DESC

Group有一些不起眼的功能,我總是不確定它是否是正確的字段......但它應該是結果集中的第一個。

你不能用GROUP BY子句解決你的問題,因為對於每組pid,MySQL只會獲取第一個pid,最大日期和找到的第一個價格(這不是你需要的)。

您可以使用子查詢(可能效率低下):

SELECT pid, date, price
FROM   ProductPrice p1
WHERE  date = ( SELECT MAX(p2.date)
                FROM ProductPrice p2
                WHERE p1.pid = p2.pid)

或者你可以簡單地加入桌子:

SELECT    p1.pid, p1.date, p1.price
FROM      ProductPrice p1
LEFT JOIN ProductPrice p2 ON p1.pid = p2.pid
          AND p1.date < p2.date
WHERE     p2.pid IS NULL

看一下MySQL文檔的這一部分

這是另一個 - 效率低下 - 一個:

SELECT pid, substring_index( group_concat( price order by date desc ), ',', 1 ) , max(date)
  FROM ProductPrice
GROUP BY pid

我認為這里的關鍵是簡單的聲音查詢 - 你可以看到你想要的東西,但計算機不是人類,因此要從基於集合的操作產生所需的結果,你必須像第二個查詢一樣明確。

內部查詢標識每個產品的最后價格,然后外部查詢允許您獲取最后價格的值 - 這就像它可以獲得的那樣簡單。

順便說一句,如果你有一個發票系統,你真的應該把產品的價格(和稅率以及“代碼”)與發票一起存儲,即發票表應該包含所有必要的財務信息來復制發票。 一般而言,您希望依賴於能夠在可變表中查找價格(或稅率),甚至允許如上所述引入的系統。 無論如何,定價歷史都有其自身的優點。

我在我的一個項目中面臨同樣的問題,我使用子查詢來獲取日期然后比較它,但是當數據增加時它會使系統變慢。 所以,除了您創建的新表以保存價格變化的歷史記錄之外,最好在Products表中存儲最新價格。

您可以隨時使用任何查詢建議,以獲得特定日期的產品的最新價格。 而且你可以在同一個表中添加一個最新的字段。 所以對於一個日期,你可以使旗幟真實一次。 您可以通過一個簡單的查詢找到特定日期的產品最新價格。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM