2016-11-21 107 views
4

我在數據庫中有四個表格,即Packages,Fixtures,Deals和Fixtures Deals。如何在Laravel 5的嵌套查詢中使用GroupBy?

下面是表的結構細節:

Packages: id, title 
Fixtures: id, package_id, name 
Deals: id, discound, description 
Fixtures_Deal: id, fixture_id, deal_id, price 

我需要與最低成交均價,提供在每個燈具的每個軟件包相處的軟件包列表。

這裏是我在phpMyAdmin或SQLYog中運行的mysql查詢,它工作正常,但在Laravel中,它給了我「p.title'不在GROUP BY」錯誤。

SELECT 
    p.title AS package_title,  
    tbl_min_value.min_price AS min_price 
FROM 
    (SELECT 
    fixture_id, 
    MIN(deal_price) AS min_price 
    FROM 
    fixture_deal 
    GROUP BY fixture_id) AS tbl_min_value 
    JOIN fixtures AS f 
    ON f.id = tbl_min_value.fixture_id 
    RIGHT JOIN packages AS p 
    ON f.package_id = p.id 
GROUP BY p.id 

順便說一句,我想通過在模型中使用下面的方法來實現它:

return DB::statement('SELECT 
     p.title AS package_title,  
     tbl_min_value.min_price AS min_price 
    FROM 
     (SELECT 
     fixture_id, 
     MIN(deal_price) AS min_price 
     FROM 
     fixture_deal 
     GROUP BY fixture_id) AS tbl_min_value 
     JOIN fixtures AS f 
     ON f.id = tbl_min_value.fixture_id 
     RIGHT JOIN packages AS p 
     ON f.package_id = p.id 
    GROUP BY p.id'); 
+0

您是否試圖以另一種方式執行它,如'$ pdo = DB :: connection() - > getPdo();'並直接啓動它 – Mruf

+0

不,我沒有嘗試過。你能否詳細說明我該怎麼做?我要寫這樣的代碼嗎?: DB :: connection() - > getPdo('Query'); –

+0

https://codeshare.io/29QA72 – Mruf

回答

2

我以雄辯收集的mapWithKeys方法發現了另一種辦法解決。

https://laravel.com/docs/5.3/collections#method-mapwithkeys 

因此,我分別提取了兩個查詢的數據,並將兩個集合都映射到一個集合對象中。

示例代碼:

$packages = Package::getPackages(); 

$deal_min_price = Deal::getMinimumPrice(); 

$packages_with_price = $packages->mapWithKeys(function ($packages) use ($deal_min_price) { 
    return $packages['price'] => $deal_min_price['min_price']; 
}); 

您既可以使用mapWithKey's closureforeach循環。

1

你所得到的錯誤是因爲MySQL 5.7移動到與SQL99更柔順。您可以閱讀關於here的一些信息,但它涉及一種稱爲ONLY_FULL_GROUP_BY的SQL模式設置,可確保選中的所有非聚合列在GROUP BY之內。這對你的情況意味着什麼?

那麼,你只需添加p.titletbl_min_value.min_price以分組爲它正常工作,因爲他們不聚集:

GROUP BY p.id, p.title, tbl_min_value.min_price 

你可能會問,「到底爲什麼他們這樣做? 」。那麼,使用GROUP BY之前,很容易意外地「倒塌」數據,其中一行有多個可能的值可顯示,所以它只顯示第一個。這使您可以使用諸如MIN()MAX()之類的聚合函數來確定要顯示的內容,或者將其添加到指示您希望將其分開的分組。

如果你不喜歡這種工作方式,你可以暫時這樣做禁用它:

# Run this query and copy the values 
SELECT @@sql_mode; 

# Remove "ONLY_FULL_GROUP_BY" and paste it in here where the XXX is 
SET sql_mode = 'XXX'; 

或者您也可以進行改變永久通過在這樣的[mysqld]部分編輯my.cnf文件,其中xxx是SELECT @@sql_mode;輸出減去ONLY_FULL_GROUP_BY部分:

[mysqld] 
sql_mode=XXX 
+0

一旦我在Group By中添加其他聚合列,它不會給我一個合適的結果,這意味着它輸出的結果有重複的ID,這就是問題所在。 此外,我試圖修改SQL模式,但它並沒有工作。 –

+0

這是因爲您有多個具有相同ID的行作爲您的連接結果。試試'GROUP_CONCAT(p.title)'和/或'GROUP_CONCAT(tbl_min_value.min_price)'來看看我的意思 –

+0

另外我想知道具有一個Group By列的相同查詢在phpMyAdmn或SQLYog中運行良好,在Laravel 5.3中工作。所以這可能是Laravel的一個問題...不確定..! –

0

這很奇怪,一個SQL查詢在phpMyAdmin工作正常,但同樣沒有在Laravel 5.3工作。你會發布帶有示例數據的數據庫結構嗎,所以我們來看看?

BTW,我嘗試以下SQL和Laravel 5.2是工作的罰款:

SELECT 
    p.title AS package_title,  
    tbl_min_value.min_price AS min_price 
FROM 
    (SELECT 
    fixture_id, 
    MIN(deal_price) AS min_price 
    FROM 
    fixtures_deal 
    GROUP BY fixture_id) AS tbl_min_value 
    JOIN fixtures AS f 
    ON f.id = tbl_min_value.fixture_id 
    RIGHT JOIN packages AS p 
    ON f.package_id = p.id 
GROUP BY p.id