如何在Laravel 5中的嵌套查询中使用GroupBy?

时间:2016-11-21 19:42:04

标签: php mysql laravel-5 group-by nested-query

我在数据库中有四个表,即包裹,固定装置,交易和固定装置交易。

以下是表结构细节:

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');

3 个答案:

答案 0 :(得分:2)

我通过使用Eloquent Collection的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'];
});

您可以在foreach中使用mapWithKey's closure循环。

答案 1 :(得分: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';

或者您可以通过编辑此my.cnf部分下的[mysqld]文件来永久更改此更改,其中XXX是SELECT @@sql_mode;的输出减去ONLY_FULL_GROUP_BY部分:

[mysqld]
sql_mode=XXX 

答案 2 :(得分:0)

奇怪的是,SQL查询在phpMyAdmin中正常工作,但在Laravel 5.3中却无法正常工作。你会发布带有样本数据的db结构,所以我们来看看?

顺便说一句,我尝试使用SQL并在[http://www.theo-android.co.uk/books/sample_data.php/q=clean][1] 中正常工作:

Laravel 5.2