Модераторы: skyboy, MoLeX, Aliance, ksnk
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как оптимизировать два запроса, выборка с подстчетом 
:(
    Опции темы
KonstRuctor
Дата 1.8.2012, 23:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 245
Регистрация: 31.3.2006
Где: Россия, Санкт-Пет ербург

Репутация: нет
Всего: нет



Есть две таблицы: страны мира и галерея фотографий.
Задача – вывести только страны, для которых есть хотя бы одно фото, в скобках общее кол-во фото для данной страны. Если фото для данной страны нет, выводит не нужно. Мои таблицы:
countries:
country_id | country
gallery:
gallery_id | title | filename | country_id
Делаю с помощью цикла:
Код

$query = "SELECT DISTINCT c.country, c.country_id, g.country_id
        FROM countries c, gallery g
        WHERE c.country_id = g.country_id
        ORDER BY c.country";
$result = $sql->query( $query );
// проходим в цикле по всему массиву
while ( $f = $sql->fetch_assoc($result) )
{
        $result_c=$sql->query("SELECT count(gallery_id) as cnt
                               FROM gallery
                               WHERE country_id = '".$f["country_id"]."'");
        $data = $sql->fetch_assoc($result_c);
        $amount = $data["cnt"];
        // выводим строку таблицы вида Россия [45]
echo $f['country'] ." [".$amount."]";
}

Хочу отделаться от запроса в цикле. Можно ли вынуть всю информацию одним запросом?
Спасибо!
PM MAIL WWW ICQ   Вверх
Fortop
Дата 2.8.2012, 00:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2200
Регистрация: 13.11.2007
Где: Донецк

Репутация: 3
Всего: 42



Код

SELECT country, cid, gid FROM (
SELECT c.country as coutnry, c.country_id as cid, count(g.id) as foto_num
        FROM countries c
        LEFT JOIN gallery g ON  c.country_id = g.country_id
        GROUP BY c.country_id
) as t
WHERE t.foto_num>0
ORDER BY country


Примерно так.


Это сообщение отредактировал(а) Fortop - 2.8.2012, 00:16


--------------------
Мир это Я.
Живее всех живых.
PM MAIL   Вверх
MaXL
Дата 2.8.2012, 03:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Developer
**


Профиль
Группа: Участник
Сообщений: 380
Регистрация: 24.10.2005
Где: Владивосток

Репутация: нет
Всего: 2



Fortop, да зачем здесь подзапросы городить.

KonstRuctor, вам нужен один запрос:
Код

SELECT c.`country` , COUNT( * )
FROM `countries` AS c
INNER JOIN `gallery` AS g ON c.`country_id` = g.`country_id`
GROUP BY c.`country`



--------------------
MaXL
PM MAIL   Вверх
KonstRuctor
Дата 2.8.2012, 13:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 245
Регистрация: 31.3.2006
Где: Россия, Санкт-Пет ербург

Репутация: нет
Всего: нет



MaXL, Работает просто молниеносно! Спасибо. 
У меня парочка таких мест есть, сделаю правильно. Разница существенная.

По ходу появилась интересная идея – вывести самое свежее фото для страны.
Разумеется, в цикле это делается просто:
Сперва делаем запрос
Код

SELECT c.`country` , COUNT( * ) AS `cnt`
FROM `countries` AS c
INNER JOIN `gallery` AS g ON c.`country_id` = g.`country_id`
GROUP BY c.`country`

и получаем перечень стран, для которых есть фотографии, причем в скобках будет общее кол-во фото.
Строим любимый цикл smile и для каждой страны из перечня вынимаем самое свежее фото (по дате)
Код

while ( $j = mysql_fetch_assoc ($result) )
{
$query = "SELECT filename
                FROM gallery
                WHERE country_id = '$j[country_id]'
                ORDER BY post_date DESC
                LIMIT 1";
........
}

Опять мой любимый вопрос: можно ли сделать и такую выборку одним запросом?
Я смог сделать, но выводится самое старое фото, а не новое

Это сообщение отредактировал(а) KonstRuctor - 2.8.2012, 16:21
PM MAIL WWW ICQ   Вверх
MaXL
Дата 3.8.2012, 05:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Developer
**


Профиль
Группа: Участник
Сообщений: 380
Регистрация: 24.10.2005
Где: Владивосток

Репутация: нет
Всего: 2



Цитата

можно ли сделать и такую выборку одним запросом?

Думаю что нет. Выбираются разные вещи smile

Вот что-то залепил, не знаю, нормально ли так писать:
Код

SELECT
  c.`country` , COUNT( * ) AS `cnt`, IF (g1.`gallery_id` IS NULL, g.`gallery_id`, g1.`gallery_id`) AS filename

FROM `countries` AS c

INNER JOIN `gallery` AS g ON c.`country_id` = g.`country_id`

LEFT JOIN `gallery` AS g1 ON
    (g1.`country_id` = g.`country_id` AND g1.`post_date` > g.`post_date`)

GROUP BY c.`country`


Вот этот код
Код

IF (g1.`gallery_id` IS NULL, g.`gallery_id`, g1.`gallery_id`) AS filename

нужен для того случая, если в базе для определённой страны есть только одно фото. уверен, это можно написать лучше.

Это сообщение отредактировал(а) MaXL - 3.8.2012, 05:29


--------------------
MaXL
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | PHP: Базы Данных | Следующая тема »


 




[ Время генерации скрипта: 0.0479 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.