2016-04-21 37 views
2

考慮以下情形:如何找到MAX以上的SUM MySQL的

an Item has a Price 

a Order contains Items 

a Delivery contains Orders 

我要查詢每一個交付,具有最高的性價比,其中一個訂單的價格是價格的總和順序包含物品。

一個簡單的足夠的模式是這樣的:

交貨

D_ID

訂購

o_id

項目

i_id,價格

ItemsInOrder

o_idi_id

OrdersInDelivery

D_IDo_id

我被困在具有求和結果來看,需要得到每交付的最大訂單:

SELECT d_id,o_id,SUM(price) 
from ItemsInOrder 
natural join OrdersInDelivery 
natural join Item 
group by d_id,o_id 

應該怎麼從這裏去得到每個d_id都會出現在最大價格總和的o_id旁邊嗎?

+0

子查詢與SUM然後選擇MAX()就可以了。 – i486

+0

如果您喜歡,請考慮遵循以下簡單的兩步操作步驟:1.如果您尚未這樣做,請提供適當的DDL(和/或sqlfiddle),以便我們可以更輕鬆地複製問題。 2.如果您尚未這樣做,請提供與步驟1中提供的信息相對應的所需結果集。 – Strawberry

+0

當兩次交付具有相同的最高價格時,您想要什麼? –

回答

0

感謝所有的答案,但他們都不是什麼我在尋找。我終於找到了我正在尋找的東西,我選擇的方法如下:

SELECT d_id,o_id,sum_price 
FROM (
    SELECT d_id,o_id,SUM(price) as sum_price 
    from ItemsInOrder 
    natural join OrdersInDelivery 
    natural join Item 
    group by d_id,o_id 
    order by d_id,sum_price desc 
) as sums 
GROUP BY d_id 
+2

使用GROUP BY這一點非常錯誤在這種情況下,服務器可以自由選擇每個組中的任何值,因此除非它們相同,否則所選的值是不確定的,這可能不是您想要的。根據MySQL文檔ion:http://dev.mysql.com/doc/refman/5.7/en/group-by-handling.html –

+2

看到這個答案:http://stackoverflow.com/a/18710186 –

+1

@OneManCrew謝謝你的提醒,這是一個非常有趣的想法,在其他情況下,你可能是對的,但在這種情況下,據我瞭解,它應該工作,因爲sum_price的功能依賴於d_id,o_id並且可以由他們唯一確定。所以這不是你提供的鏈接中描述的情況。 –

0

請勿使用natural join。它們是一個等待發生的錯誤,因爲它們依賴表中列的名稱 - 甚至不使用正確和明確定義的外鍵關係。改爲使用onusing

這種類型的查詢在MySQL中很痛苦,因爲MySQL不支持CTE(公用表表達式),也不支持窗口函數。因此,查詢比其他數據庫更爲複雜:

select oid.d_id, o_id, SUM(price) 
from OrdersInDelivery oid join 
    ItemsInOrder iio 
    using (o_id) 
    Item i 
    using (i_id) 
group by d_id, o_id 
having sum(price) = (select sum(iio2.price) 
        from ItemsInOrder iio2 join 
          Item i2 
          using (i_id) 
        where iio2.d_id = iio.d_id 
        group by iio2.o_id 
        order by sum(iio2.price) desc 
        limit 1 
        ); 
+0

如何定義在原始問題中的查詢結果在臨時表中,然後在最大查詢中使用它? –

+0

除非絕對必要,否則我寧願不使用臨時表。在這種情況下,它確實簡化了查詢,並且 - 如果添加一個索引 - 可能會使速度更快。 –

0

我分享,我已經到目前爲止任何人都可以繼續幫助你,因爲我現在需要離開機場得到的結果:)我如果沒有人知道,明天再試一次。

它是一個具有挑戰性的問題傢伙。

我已經準備了一些樣品在這裏: http://sqlfiddle.com/#!9/d4fed2

,我做最新的查詢是:

SELECT d_id,OID.o_id,sumPrice 
from OrdersInDelivery OID 
join (SELECT IIO.o_id,SUM(I.price) as sumPrice 
from ItemsInOrder IIO 
join item I on I.i_id = IIO.i_id 
group by IIO.o_id) IIO1 on OID.o_id = IIO1.o_id 

祝你好運:)

2

您可以使用左自加入,調整加入條件和過濾器。 在這種方法中,您將自己與表連接在一起。平等,當然,在組標識符。

SELECT a.* 
FROM (
     SELECT oid.d_id AS d_id, o_id, SUM(price) AS sum_price 
     FROM `OrdersInDelivery` oid 
     INNER JOIN `ItemsInOrder` iio USING (o_id) 
     INNER JOIN `Item` i USING (i_id) 
     GROUP BY d_id, o_id 
    ) a 
LEFT OUTER JOIN (
        SELECT oid.d_id AS d_id, o_id, SUM(price) AS sum_price 
        FROM `OrdersInDelivery` oid 
        INNER JOIN `ItemsInOrder` iio USING (o_id) 
        INNER JOIN `Item` i USING (i_id) 
        GROUP BY d_id, o_id 
       )b 
    ON a.d_id = b.d_id AND a.sum_price < b.sum_price 
WHERE b.d_id IS NULL AND b.o_id IS NULL; 

看看這個查詢的SQL小提琴:http://sqlfiddle.com/#!9/d5c04d/1

在這種情況下,建議使用TEMPORARY TABLE

CREATE TEMPORARY TABLE OrderSummary(
    SELECT oid.d_id AS d_id, o_id, SUM(price) AS sum_price 
      FROM `OrdersInDelivery` oid 
      INNER JOIN `ItemsInOrder` iio USING (o_id) 
      INNER JOIN `Item` i USING (i_id) 
      GROUP BY d_id, o_id 
    ); 
CREATE TEMPORARY TABLE OrderSummary2(
    SELECT * FROM OrderSummary 
    ); 

    SELECT a.* 
    FROM OrderSummary a 
    LEFT OUTER JOIN OrderSummary2 b 
     ON a.d_id = b.d_id AND a.sum_price < b.sum_price 
    WHERE b.d_id IS NULL AND b.o_id IS NULL; 
+0

感謝您的回答,但是這種方法增加了不必要的連接和代碼複雜性,而且臨時表可能會導致性能問題,因爲丟失了適當的索引。 –