SQLinfo.ru - Все о MySQL

Форум пользователей MySQL

Задавайте вопросы, мы ответим

Вы не зашли.

#1 16.03.2010 21:00:57

mikki11
Участник
Зарегистрирован: 14.03.2010
Сообщений: 14

Сложный вложенный запрос

Нужно чтобы на сайте выводились марки, и для каждой марки её модели+число тачек в каждой модели:
AUDI
-80 (2 авто)
-100 (1 авто)
-TT (6 авто)

BMW
-318 (2 авто)

NISSAN
-Terrano (1 авто)
-Sunny (1 авто)

Но таким образом, чтобы выводились лишь те марки и модели, тачки для которых ЕСТЬ в базе.
Например в ьазе забито около 100 марок, и хотябы для BMW вбито около 20 моделей (545, 745, 316, X3, Z3 и тд)
Но в базе у нас лишь 2 тачки BMW модели 318, а посему мы выводит только то что имеется.







function list_marks($domain_city) {
    global $xtpl, $db;

    // Указали город - ищем марки только этого города
    if($domain_city != '') {
        $result = $db->QueryResult("SELECT DISTINCT t1.mark_id,         t1.mark_name FROM                                 ".MARKS_TABLE." AS t1, ".USERS_TABLE." AS t2,                 ".CARS_TABLE." AS t3 WHERE t1.mark_id IN (SELECT             DISTINCT mark_id FROM ".CARS_TABLE.") AND                 t2.user_city='$domain_city' AND t2.user_id=t3.user_id         AND t1.mark_id=t3.mark_id AND t1.mark_checked='on' ORDER         BY t1.mark_name");
    }
    // Город не указан - ищем марки по всей России
    else {
        $result = $db->QueryResult("SELECT DISTINCT t1.mark_id,         t1.mark_name FROM                                 ".MARKS_TABLE." AS t1, ".USERS_TABLE." AS t2,                 ".CARS_TABLE." AS t3 WHERE t1.mark_id IN (SELECT             DISTINCT mark_id FROM ".CARS_TABLE.") AND                 t2.user_id=t3.user_id AND t1.mark_id=t3.mark_id AND             t1.mark_checked='on' ORDER BY t1.mark_name");
    }

    //Для каждой марки собираем её модели
    while($row = $db->FetchResult($result)) {
        // Указали город - ищем модели только для этого города
        if($domain_city != '') {
                $result2 = $db->QueryResult("SELECT DISTINCT                 t1.model_id, t1.model_name FROM ".MODELS_TABLE."             AS t1, ".USERS_TABLE." AS t2, ".CARS_TABLE." AS t3             WHERE t1.mark_id='$row[mark_id]' AND t1.model_id             IN (SELECT DISTINCT model_id FROM ".CARS_TABLE.")             AND t2.user_city='$domain_city' AND                     t2.user_id=t3.user_id AND t1.model_id=t3.model_id             AND t1.model_checked='on' ORDER BY                         t1.model_name");
        }
        // Город не указан - ищем модели по всей России
        else {
            $result2 = $db->QueryResult("SELECT DISTINCT                 t1.model_id, t1.model_name FROM ".MODELS_TABLE."             AS t1, ".USERS_TABLE." AS t2, ".CARS_TABLE." AS t3             WHERE t1.mark_id='$row[mark_id]' AND t1.model_id             IN (SELECT DISTINCT model_id FROM ".CARS_TABLE.")             AND                                             t2.user_id=t3.user_id AND t1.model_id=t3.model_id             AND t1.model_checked='on' ORDER BY                         t1.model_name");
        }

        // Выводим полученные модели данной марки - 2-й дескриптор открываем
        while($row2 = $db->FetchResult($result2)) {
        // пишем имя модели
        echo $row2[model_name];
        // вызываем внешнюю ф-ю которая считает сколько тачек принадлежат данной модели. Она также коннектится к базе.
        echo get_models_number($row2[model_id]);
        }
    }
    // пишем имя марки
    echo $row[mark_name];
}

А таблицы такие (упрощённый вариант):

MARKS_TABLE:
-mark_id
-mark_name

MODELS_TABLE:
-model_id
-model_name
-mark_id

CARS_TABLE:
-car_id
-mark_id
-model_id
-user_id

USERS_TABLE:
-user_id
-user_city



Как видите, идёт целых 3 запроса к BD:
1. Для каждой марки {
    2. Для каждой модели данной марки {
        3. Опять ломимся в базу для получения кол-ва тачек данной модели
    }
}

Хотелось бы чтобы этот запрос в 1 объединить. Да и вообще - оптимизировать. В этих 4-х таблицах поля пересекаются между собой и зависимы друг от друга. Именно поэтому мне приходится делать такой длинный запрос чтобы приравнять всевозможные комбинации полей.

Отредактированно mikki11 (16.03.2010 21:06:16)

Неактивен

 

#2 16.03.2010 21:19:14

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Сложный вложенный запрос

SELECT m.name, COUNT(*)
FROM CARS_TABLE c
JOIN MODELS_TABLE m USING (model_id)
WHERE m.mark_id = ? -- например, номер ауди
GROUP BY 1;

А остальные две таблички не нужны wink

Ну или если с названиями марок
SELECT mm.name, m.name, COUNT(*)
FROM CARS_TABLE c
JOIN MODELS_TABLE m USING (model_id)
JOIN MARKS_TABLE mm ON mm.mark_id = m.mark_id
GROUP BY 1,2;

К слову сказать, CARS_TABLE(mark_id) — лишнее.

Неактивен

 

#3 16.03.2010 21:31:13

mikki11
Участник
Зарегистрирован: 14.03.2010
Сообщений: 14

Re: Сложный вложенный запрос

paulus, распишите пожалуйста запрос более конкретно. Всмысле не 'm' или 'mm', а 'mark_id' или 'model_name' и тд. Чтобы я знал где и какие поля. Просто уже крыша едет и я начинаю тупить над элементарными вещами. У меня ещё запросов штук 10-15 подобных, + индексы надо где-нить наставить, да и типы полей в порядок привести. Естественно, если вы согласитесь со всем этим помочь - заплачу по WMR (цену обсудим). Ну а этот запрос плиз распишите с реальными именами полей, нахаляву -)

Неактивен

 

#4 16.03.2010 21:40:14

vasya
Архат
MySQL Authorized Developer
Откуда: Орел
Зарегистрирован: 07.03.2007
Сообщений: 5842

Re: Сложный вложенный запрос

Он и так с ральными полями, за исключением:
mm.name --> mm.mark_name
m.name  --> m.model_name

mikki11 написал:

Просто уже крыша едет и я начинаю тупить над элементарными вещами.

Утро вечера мудрееwink А так только время зря потеряете.

Неактивен

 

#5 16.03.2010 21:40:37

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Сложный вложенный запрос

Эти запросы реально будут работать wink
Ну только вместо знака вопроса надо подставить id соответствующей марки.

UPD: Кстати, действительно, имена почему-то решил, что просто name…

Неактивен

 

#6 16.03.2010 21:41:24

mikki11
Участник
Зарегистрирован: 14.03.2010
Сообщений: 14

Re: Сложный вложенный запрос

а всё я разобрался. сенькс - завтра на работу приду и попробую.
Итак - сколько вы будете за 1подобный запрос брать? Яготов платить - главное чтоб грамотные и быстрые запросы были.

Неактивен

 

#7 16.03.2010 21:42:58

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Сложный вложенный запрос

Ответы на форуме у нас традиционно бесплатные, а платные услуги у нас есть
в cоответствующем разделе smile

Неактивен

 

#8 16.03.2010 21:50:41

mikki11
Участник
Зарегистрирован: 14.03.2010
Сообщений: 14

Re: Сложный вложенный запрос

Я почитал - 8тр за оптимизацию. Но у меня сложный довольно-таки сайт. Там всё работает за исключением 1 момента - запросы все надо привести из таких как я написал - в ваши. Во всех ф-ях сайта. За 8 тр уложусь?

Неактивен

 

#9 17.03.2010 11:10:42

mikki11
Участник
Зарегистрирован: 14.03.2010
Сообщений: 14

Re: Сложный вложенный запрос

paulus написал:

Ну или если с названиями марок
SELECT mm.name, m.name, COUNT(*)
FROM CARS_TABLE c
JOIN MODELS_TABLE m USING (model_id)
JOIN MARKS_TABLE mm ON mm.mark_id = m.mark_id
GROUP BY 1,2;

К слову сказать, CARS_TABLE(mark_id) — лишнее.

Ну а во-первых, как мне их через echo выводить чтобы получилось нечто вроде:
AUDI
-100 (2 авто)
-TT (1 авто)

BMW
-318 (6 авто)

И как будет выглядеть запрос если город будет присутствовать, типа авто тока с определённого города?

Неактивен

 

#10 17.03.2010 18:54:09

paulus
Администратор
MySQL Authorized Developer and DBA
Зарегистрирован: 22.01.2007
Сообщений: 6757

Re: Сложный вложенный запрос

Про вывод — вопросы по php следует задавать на webew.ru.
Про город — нужно перед группировкой добавить WHERE c.city_id = $city_id.

Неактивен

 

Board footer

Работает на PunBB
© Copyright 2002–2008 Rickard Andersson