Русское сообщество разработки на PHP-фреймворке Laravel.
Ты не вошёл. Вход тут.
Страницы 1
Добрый вечер уважаемое Сообщество.
Не спрашивайте зачем это надо, к сожалению, не всегда архитектура системы позволяет сделать по-человечески, и изредка приходится ставить "костыли"... Итак, есть примерно такая таблица (будем мучать как пример вечно запиленную автомобильную тему):
price_table
id, field1, field2, field3, price, id_firm, hash
Поле "hash" это уникальное поле, показывающее наличие одного и того же автомобиля у разных источников информации. Необходимо выбрать одну строку группируясь по хешу и указать количество одинаковых хешкодов существующих в разных источниках.
Запрос вот такой:
SELECT
p1.*,
(SELECT count(*) FROM price_table p2 WHERE p2.hash = p1.hash) as count_hash
FROM
price_table p1
WHERE ...
GROUP BY p1.hash
ORDER BY ...
LIMIT ...
OFFSET ...
все получается кроме вот только конструкции вложенного селекта этого... Подскажите возможно ли так сделать в Fluent Query или ставить RAW запрос полный и забить на внутренние эти всякие "вспомогалки"?
Не в сети
Не в сети
Куда пиво/кофе/водку слать?.. ))
Блин, у меня тут крышу уносило уже, начал с JOIN и прочими вещами закапываться... А простое решение даже не попробовал... Чегой-то казалось что... вобщем ну его... пора спать
PS: одна только проблема еще осталась, попробую ее раскопать, но интересная...
При этом запросе данные соответственно передаются в $db->paginate, а уже Paginator штатный, делает первый запрос
SELECT COUNT(id) AS `aggregate` FROM `cars` GROUP BY hash_code
Как итог, получаем количество страниц равное 1. Если исключаем GROUP_BY, то соответственно все работает корректно... кроме самого запроса...
Изменено Vertex (25.10.2012 09:24:08)
Не в сети
Не в сети
Да мне и самому Framework понравился... Достаточно чистая структура, нет тесно интегрированных навесок типа как в Yii, быстрый, не глюкавит как FuelPHP, очень легкий старт (напоминает Codeigniter по этому пункту), ну и не такой грузивный как Symfony и Zend, единственный это Paginator, который в принципе перекрыл уже. Не хватает немного информации расширенной конечно по нему, но благодаря таким как Вы, получил ответы на все вопросы. Некоторые вопросы еще на IRC-канале также очень много людей.
Блин... дурдом... 5-ый раз изменяю эту запись... цирк...
Вобщем никак не получается выполнить такую последовательность:
Запрос 1:
SELECT COUNT(DISTINCT hash_code) AS `aggregate` FROM `cars`
Запрос 2:
SELECT
f1.hash_code, f1.field1, f1.field2
count(firm_code) as cntm, max(f1.price) as price_max, min(f1.price) as price_min
FROM
`cars` f1
GROUP BY f1.hash_code
ORDER BY cntm DESC
Т.е. насколько я понимаю все-таки группировку где-то надо убирать, но в этом случае, соответственно требуется уже не использовать функцию paginate, а генерировать линки вручную?
Ну или добавить в ядро "заплатку"... но как же я такие заплатки ненавижу... обновить потом ядро хрен выйдет. Надо расковырять как можно расширять ядро выносами.
public function paginate_with_group_by($per_page = 20, $columns = array('*'))
{
// Because some database engines may throw errors if we leave orderings
// on the query when retrieving the total number of records, we'll drop
// all of the ordreings and put them back on the query.
list($orderings, $this->orderings) = array($this->orderings, null);
$temp_distinct = $this->distinct;
$temp_groups = $this->groupings;
$this->distinct();
$this->groupings = null;
$total = $this->count(reset($columns));
$this->distinct = $temp_distinct;
$this->groupings = $temp_groups;
$page = Paginator::page($total, $per_page);
$this->orderings = $orderings;
// Now we're ready to get the actual pagination results from the table
// using the for_page and get methods. The "for_page" method provides
// a convenient way to set the paging limit and offset.
$results = $this->for_page($page, $per_page)->get($columns);
return Paginator::make($results, $total, $per_page);
}
Изменено Vertex (25.10.2012 14:43:04)
Не в сети
- Не хватает немного информации расширенной конечно по нему, но благодаря таким как Вы, получил ответы на все вопросы.
На самом деле лучшая документация — сам код. Я ведь половину ответов на этом форуме, если не больше, беру именно оттуда — пока ещё я не запомнил всё и вся о нём. У Laravel компактный код, много комментариев, можно быстро разобраться, что к чему. На крайний случай есть отладчик.
- Ну или добавить в ядро «заплатку»… но как же я такие заплатки ненавижу…
Сделай статичный класс или файл с полезными функциями и складывай обёртки туда. Для этого конкретного случая расширять Paginator или Query не нужно, поэтому можно обойтись обёрткой.
Код я примерно таким себе и представлял — единственное, как его можно упростить — вычислить count до того, как добавлять distinct/group by и создавать Paginator напрямую, передавая ему эту сумму. Но в одну функцию это не обернёшь, поэтому «автоматический» вариант только как у тебя.
Не в сети
То что код там более чем нормально написанный, это да, читается легко. А при помощи PHPStorm так вообще никаких проблем. Но вот задаю вопросы для того чтобы узнать "True Way". Т.е. те кто уже давно пишут на фреймворке те уже выработали какой-то набор правил, куда выносить "обертки", какие способы расширения...
Query, к сожалению, пришлось заменить в коде, так как там жестко прописано было use Laravel/Paginator, и неважно что было переназначено... Хотя я еще не разобрался с автозагрузкой, в теории может получится переназначить alias. Разбираю фреймворк на реальном проекте, и сроки немного поджимали, а от Codeigniter я чешусь уже...
Не в сети
- Т.е. те кто уже давно пишут на фреймворке те уже выработали какой-то набор правил, куда выносить «обертки», какие способы расширения…
Нет такого понятия «true way», нет. Я давно пишу и на PHP, и на других языках и всегда убеждался, что понятие «правильно» — субъективное и варьируется от человека к человека или в случае с командой — от одной команды/проекта к другой.
Может быть понятие «красивый код», «краткий код», «рабочий код», но всё это как раз можно достать из первоисточника — кода фреймворка.
- Хотя я еще не разобрался с автозагрузкой, в теории может получится переназначить alias.
Не получится. Это одна из проблем Laravel — весь его код написан внутри PHPnamespace Laravel\...;
, что значит, что алиасы (как они заданы в application/config/application.php) вообще никак не влияют на код фреймворка. Они чисто для нашего удобства.
Единственный вариант без изменения кода библиотеки — переписывать методы, где жёстко прописаны эти классы (как PHPPaginator
). Есть несколько методов, специально только конструирующие объект (например, PHPModel->query()
), но их часто бывает мало.
Не в сети
А планируется переработка Laravel для возможности изменения ядра или это приницпиальное у разработчика (типа bcrypt'a)? Просто подумываю, может форкнуть...
Не в сети
Не в сети
sqlSELECT f1.hash_code, f1.field1, f1.field2 count(firm_code) as cntm, max(f1.price) as price_max, min(f1.price) as price_min FROM `cars` f1 GROUP BY f1.hash_code ORDER BY cntm DESCТ.е. насколько я понимаю все-таки группировку где-то надо убирать
Если хочется решить задачу в рамках SQL, есть два способа:
sqlmax(field1) field1, max(field2) field12
, если по смыслу их значения одинаковы.Правильно ведь понимаю, что эти поля — из справочника? Если нет, постановка неверна.
Не в сети
Freeman, спасибо в любом случае, вопрос уже решен... просто выспаться надо было...
Не в сети
Страницы 1