Страница 1 из 1
Как правильно построить запрос в yii2, чтобы с каждой категории бралось по одной записи?
Добавлено: 2020.05.01, 21:36
alexa777
Вот запрос:
Код: Выделить всё
$query = self::find()->select('id, title, url, img, img_thumb, category_id')
->where(['status' => 1])
->andWhere(['in', 'category_id', $array_category_id])
->orderBy(new Expression('rand()'))
->limit(10)
->asArray()->all();
$array_category_id - здесь 10 айдишников разных категорий, надо чтобы выборка была по одной записи с каждой категории
Как это сделать?
Re: Как правильно построить запрос в yii2, чтобы с каждой категории бралось по одной записи?
Добавлено: 2020.05.03, 01:12
samdark
А как бы вы это сделали в SQL?
Re: Как правильно построить запрос в yii2, чтобы с каждой категории бралось по одной записи?
Добавлено: 2020.05.03, 13:35
alexa777
samdark писал(а): ↑2020.05.03, 01:12
А как бы вы это сделали в SQL?
В SQL у меня получилось только так через временную таблицу
Код: Выделить всё
create TEMPORARY TABLE ids(id int);
insert into ids(id)
select (select id from news n2 where n2.category_id = n1.category_id order by rand() limit 1)
from news n1
where category_id in (1,2,3)
and status =1
group by category_id;
select * from news where id in (select * from ids)
Но я не уверен что это самый оптимальный вариант
Re: Как правильно построить запрос в yii2, чтобы с каждой категории бралось по одной записи?
Добавлено: 2020.05.03, 16:23
gerzog1995
Код: Выделить всё
Category::find()->from(Category::find()->select('category.id AS cid, news.id AS nid, news.text,news.title, news.url, news.img, news.img_thumb, news.category_id')
->innerJoin('news as n', 'category.id = n.category_id')->orderBy('rand()'))
->where(['status' => 1])
->andWhere(['cid' => $array_category_id])
->groupBy('cid')->asArray()->all();
Я бы сделал так, не знаю, верно или нет, просто может помогу чем-то или идею подам
Re: Как правильно построить запрос в yii2, чтобы с каждой категории бралось по одной записи?
Добавлено: 2020.05.03, 17:41
alexa777
gerzog1995 писал(а): ↑2020.05.03, 16:23
Код: Выделить всё
Category::find()->from(Category::find()->select('category.id AS cid, news.id AS nid, news.text,news.title, news.url, news.img, news.img_thumb, news.category_id')
->innerJoin('news as n', 'category.id = n.category_id')->orderBy('rand()'))
->where(['status' => 1])
->andWhere(['cid' => $array_category_id])
->groupBy('cid')->asArray()->all();
Я бы сделал так, не знаю, верно или нет, просто может помогу чем-то или идею подам
Сходу попробовал, не получилось, выдало ошибку
Код: Выделить всё
PDOException: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'news.id' in 'field list' i
Но спасибо попробую поиграть с ним
Re: Как правильно построить запрос в yii2, чтобы с каждой категории бралось по одной записи?
Добавлено: 2020.05.03, 17:49
gerzog1995
Я таблицы заменил, не знаю какие у вас там, перепишите под свои таблицы и должно в итоге получится то, что вы хотите.
Re: Как правильно построить запрос в yii2, чтобы с каждой категории бралось по одной записи?
Добавлено: 2020.05.03, 19:02
alexa777
gerzog1995 писал(а): ↑2020.05.03, 17:49
Я таблицы заменил, не знаю какие у вас там, перепишите под свои таблицы и должно в итоге получится то, что вы хотите.
у меня они и есть category и news
Re: Как правильно построить запрос в yii2, чтобы с каждой категории бралось по одной записи?
Добавлено: 2020.05.04, 09:29
gerzog1995
from(Category::find()->select('category.id AS cid, news.id AS nid, n.text,n.title, n.url,n.img, n.img_thumb, n.category_id')
Замените news.* на псевдоназвание n.* и должно работать
Re: Как правильно построить запрос в yii2, чтобы с каждой категории бралось по одной записи?
Добавлено: 2020.05.04, 10:01
alexa777
gerzog1995 писал(а): ↑2020.05.04, 09:29
from(Category::find()->select('category.id AS cid, news.id AS nid, n.text,n.title, n.url,n.img, n.img_thumb, n.category_id')
Замените news.* на псевдоназвание n.* и должно работать
попробовал
Код: Выделить всё
PDOException: SQLSTATE[42000]: Syntax error or access violation: 1055 Expression #2 of SELECT list is not in GROUP BY clause and contains nonaggregated column '0.nid' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by
Re: Как правильно построить запрос в yii2, чтобы с каждой категории бралось по одной записи?
Добавлено: 2020.05.05, 09:00
unknownby
Попробуй так, а то у тебя два раза ругается на твой
'news.id' или
'0.nid'
Код: Выделить всё
Category::find()->from(Category::find()->select('category.id AS cid, n.*')
->innerJoin('news as n', 'category.id = n.category_id')->orderBy('rand()'))
->where(['status' => 1])
->andWhere(['cid' => $array_category_id])
->groupBy('cid')->asArray()->all();
Re: Как правильно построить запрос в yii2, чтобы с каждой категории бралось по одной записи?
Добавлено: 2020.05.06, 20:24
alexa777
unknownby писал(а): ↑2020.05.05, 09:00
Попробуй так, а то у тебя два раза ругается на твой
'news.id' или
'0.nid'
Код: Выделить всё
Category::find()->from(Category::find()->select('category.id AS cid, n.*')
->innerJoin('news as n', 'category.id = n.category_id')->orderBy('rand()'))
->where(['status' => 1])
->andWhere(['cid' => $array_category_id])
->groupBy('cid')->asArray()->all();
Тожке ошибка
Код: Выделить всё
SQLSTATE[42000]: Syntax error or access violation: 1055 Expression #2 of SELECT list is not in GROUP BY clause and contains nonaggregated column '0.id' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by
Re: Как правильно построить запрос в yii2, чтобы с каждой категории бралось по одной записи?
Добавлено: 2020.05.07, 07:29
unknownby
Можно ли как-то узнать, что есть в системе и что предполагается сделать?
Может есть более деликатный способ, чем делать непонятной конструкции запрос.
P.S.
alexa777 писал(а): ↑2020.05.01, 21:36
$array_category_id - здесь 10 айдишников разных категорий, надо чтобы выборка была по одной записи с каждой категории
Как это сделать?
Ну так ответ лежит на поверхности. Во-1 имеется уже 10
РАЗНЫХ идентификаторов категорий. А следовательно нужно вывести что-то из новостей, где присутствует данный
category_id в категории.
Код: Выделить всё
$query = News::find()
->andWhere(['in', 'category_id', $array_category_id])
->groupBy('category_id')
->orderBy(new Expression('rand()'))
->all();
А если нужно что-то вывести из самой таблицы категорий, то первый запрос должен работать, можно убрать даже limit(10), если всегда будет передаваться по 10 штук
category_id
Re: Как правильно построить запрос в yii2, чтобы с каждой категории бралось по одной записи?
Добавлено: 2020.05.07, 21:10
alexa777
unknownby писал(а): ↑2020.05.07, 07:29
Можно ли как-то узнать, что есть в системе и что предполагается сделать?
Может есть более деликатный способ, чем делать непонятной конструкции запрос.
P.S.
alexa777 писал(а): ↑2020.05.01, 21:36
$array_category_id - здесь 10 айдишников разных категорий, надо чтобы выборка была по одной записи с каждой категории
Как это сделать?
Ну так ответ лежит на поверхности. Во-1 имеется уже 10
РАЗНЫХ идентификаторов категорий. А следовательно нужно вывести что-то из новостей, где присутствует данный
category_id в категории.
Код: Выделить всё
$query = News::find()
->andWhere(['in', 'category_id', $array_category_id])
->groupBy('category_id')
->orderBy(new Expression('rand()'))
->all();
А если нужно что-то вывести из самой таблицы категорий, то первый запрос должен работать, можно убрать даже limit(10), если всегда будет передаваться по 10 штук
category_id
Такой запрос я сразу пробовал, не работает, groupBy требует агрегатную функцию
SQLSTATE[42000]: Syntax error or access violation: 1055 Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'base.news.id' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by
The SQL being executed was: SELECT * FROM `news` WHERE `category_id` IN ('13', '8', '3', '10', '9', '11', '12', '14', '15', '17') GROUP BY `category_id` ORDER BY rand()
Error Info: Array
(
[0] => 42000
[1] => 1055
[2] => Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'base.news.id' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by
)
Re: Как правильно построить запрос в yii2, чтобы с каждой категории бралось по одной записи?
Добавлено: 2020.05.08, 10:00
gerzog1995
скинь пожалуйста структуру бд с таблицами для запроса
Re: Как правильно построить запрос в yii2, чтобы с каждой категории бралось по одной записи?
Добавлено: 2020.05.17, 09:34
alexa777
gerzog1995 писал(а): ↑2020.05.08, 10:00
скинь пожалуйста структуру бд с таблицами для запроса
База category - id | name
База news - id | title | url | img | img_thumb | category_id
Re: Как правильно построить запрос в yii2, чтобы с каждой категории бралось по одной записи?
Добавлено: 2020.05.17, 13:13
lavros
Можно сделать через подзапрос:
Код: Выделить всё
SELECT *
FROM news
WHERE
id IN (
SELECT MAX(id)
FROM news
WHERE category_id IN (13, 8, 3, 10, 9, 11, 12, 14, 15, 17)
GROUP BY category_id
)
В подзапросе используем MAX(id) чтобы при группировке по category_id не получить ошибку группировки данных: 1055 Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column...
По сути, получилось что мы получим последние новости в этих категориях.
Код: Выделить всё
$subQuery = self::find()
->select(new Expression('MAX(id)'))
->where(['category_id' => $array_category_id])
->groupBy('category_id');
$query = self::find()
->select('id, title, url, img, img_thumb, category_id')
->where(['in', 'id', $subQuery])
->andWhere(['status' => 1])
->orderBy(new Expression('rand()'))
->asArray()
->all();
Re: Как правильно построить запрос в yii2, чтобы с каждой категории бралось по одной записи?
Добавлено: 2020.05.20, 20:05
alexa777
lavros писал(а): ↑2020.05.17, 13:13
Можно сделать через подзапрос:
Код: Выделить всё
SELECT *
FROM news
WHERE
id IN (
SELECT MAX(id)
FROM news
WHERE category_id IN (13, 8, 3, 10, 9, 11, 12, 14, 15, 17)
GROUP BY category_id
)
В подзапросе используем MAX(id) чтобы при группировке по category_id не получить ошибку группировки данных: 1055 Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column...
По сути, получилось что мы получим последние новости в этих категориях.
Код: Выделить всё
$subQuery = self::find()
->select(new Expression('MAX(id)'))
->where(['category_id' => $array_category_id])
->groupBy('category_id');
$query = self::find()
->select('id, title, url, img, img_thumb, category_id')
->where(['in', 'id', $subQuery])
->andWhere(['status' => 1])
->orderBy(new Expression('rand()'))
->asArray()
->all();
Спасибо, попробую