2016-11-21 1 views
4

У меня есть четыре таблицы в базе данных, то есть пакеты, светильники, предложения и светильники.Как использовать GroupBy во вложенном запросе в Laravel 5?

Вот детали структуры таблицы:

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

Мне нужно, чтобы получить список пакетов наряду с минимальной ценой сделки, которая предлагает в каждом приспособлении для каждого пакета.

Вот запрос mysql, который я запускаю в phpMyAdmin или SQLYog, и он отлично работает, но в 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']; 
}); 

Вы можете использовать либо foreach петлю в mapWithKey's closure.

1

ошибка, вы получаете, потому что MySQL 5.7 переехал быть более сговорчивым с SQL99. Вы можете немного прочитать об этом here, но он включает в себя настройку режима SQL, называемую ONLY_FULL_GROUP_BY, которая обеспечивает выбор любых неагрегированных столбцов внутри GROUP BY. Что это значит для вашей ситуации?

Ну, вам просто нужно добавить p.title и tbl_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 
+0

После того, как я добавил другие агрегированные столбцы в Group By, он не дает мне соответствующих результатов, что означает вывод результатов с дублирующимися идентификаторами, что является проблемой. Кроме того, я попытался изменить режим SQL, но он не работал. –

+0

Это потому, что у вас есть несколько строк с одинаковым идентификатором в результате ваших объединений. Попробуйте 'GROUP_CONCAT (p.title)' и/или 'GROUP_CONCAT (tbl_min_value.min_price)', чтобы увидеть, что я имею в виду –

+0

. Также мне было интересно, что тот же запрос, имеющий один столбец Group By, хорошо работает в phpMyAdmn или SQLYog, t в Laravel 5.3. Так что это может быть проблемой с Laravel ... Не уверен ...! –

0

это странно, что SQL-запрос работает нормально в PhpMyAdmin, но то же не работает в Laravel 5.3. Вы опубликовали бы структуру db с образцами данных, чтобы мы посмотрели?

Кстати, я попытался следующий 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 
Смежные вопросы