Модераторы: skyboy
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Помогите с запросом, Нужна помощь 
:(
    Опции темы
Staser
  Дата 28.10.2006, 03:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 15.7.2006

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



Как сделать нормальный (правильно работающий) запрос типа SELECT COUNT(*)...;

Из такого вот запроса:
Код

SELECT DISTINCT
    `uid`,
    `fid`
FROM
    `list`
WHERE
    `uid` IN (
SELECT DISTINCT
    `uid`
FROM
    `list`
WHERE
    `fid` IN (
SELECT DISTINCT
    `uid`
FROM
    `list`
WHERE
    `fid`=%ID% )
    AND
        `fid`!=%ID% )
    AND
        `fid`!=%ID%
    AND
        `list`.`fid` NOT IN (
SELECT
    `fid`
FROM
    `list`
WHERE
    `uid`=%ID% )
    AND 
        `list`.`fid` NOT IN (
SELECT
    `fid`
FROM
    `list`
WHERE
    ( `uid` IN (
SELECT
    `uid`
FROM
    `list`
WHERE
    `fid`=%ID% ) ) )
GROUP BY
    `fid`
LIMIT
    6


Проблемы которые следует решить:
  •  При 0 кол-ве (отсутствии записей 3го уровня), должно возвращать COUNT(*) -> 0 однако невозвращает ничего. (0 рядов)
  •  При наличии более одного пути к данной зависимости выводит их все, при простом выводе от этого спасает простая группировка, однако при выборе COUNT, насчитывает лишние пути..
  •  По возможности оптимизировать запрос


Это сообщение отредактировал(а) Staser - 28.10.2006, 18:41
PM MAIL   Вверх
comtat
Дата 28.10.2006, 10:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1310
Регистрация: 2.5.2006
Где: Россия, Казань

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



Какие ошибки заметил сразу 
Код
SELECT DISTINCT    `uid`,    `fid`, FROM    `list`

перед FROM запятой не нужно ставить
За чем нужна такая конструкция 
Код
`uid`=%ID%

Я не понимаю, наверное имелось в виду, если ID число, то тогда  
Код
`uid`=ID


Это сообщение отредактировал(а) comtat - 28.10.2006, 10:35


--------------------
Рожденный в СССР !!!
ExtJS - мой фреймворк 
PM   Вверх
Staser
Дата 28.10.2006, 13:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 15.7.2006

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



Первая ошибка, это я не заметил когда вырезал _лишнее_ из запроса, важна сама суть...
%ID% - это некая переменная в скрипте, который делает запрос...

И всёже, так никто и не помог, вопрос тот же...
PM MAIL   Вверх
muzer
Дата 28.10.2006, 16:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 387
Регистрация: 31.8.2006

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



Staser, вы издеваетесь? smile

Подскажу, как правильно задать вопрос:
привести show create table, описать какое поле что значит, сформулировать словами, какого результата пытаетесь добиться, тогда вам помогут. 

А то представьте, я щас приведу какой-нить запрос (типа того, что ниже) и скажу "помогите, не работает" smile
Код

SELECT
        T.NeedInfo1,
        T.NeedInfo3,
        T.NeedInfo2,
        L.SomeVal
FROM
(
        SELECT
                H.SomeTopValID,
                H.SomeValID,
                SUM(S.NeedInfo1) AS NeedInfo1,
                SUM(S.NeedInfo3) AS NeedInfo3,
                H.NeedInfo2
        FROM
        (
                SELECT
                        SomeTopValID,
                        SomeValID,
                        COUNT(*) AS NeedInfo2
                FROM
                        SomeValHistory
                WHERE
                                SomeTopValID = $SomeTopValid
                        AND
                                SomeTime1 > NOW() - INTERVAL 3 DAY
                GROUP BY
                        SomeValID
        ) H
        INNER JOIN
                SomeValStat S
                USING(SomeTopValID,SomeValID)
        WHERE
                S.SomeTime2 > NOW() - INTERVAL 3 DAY
        GROUP BY
                SomeValID
        ORDER BY
                NeedInfo2 DESC
        LIMIT
                $limit
) T
INNER JOIN
        SomeValLog L
        USING(SomeTopValID,SomeValID)
ORDER BY
        T.NeedInfo2 DESC

PM WWW   Вверх
Staser
Дата 28.10.2006, 18:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 12
Регистрация: 15.7.2006

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



 smile 

Ну вот таблица, (значительно упрощённая)
Код

CREATE TABLE `list` (
  `uid` int(11) NOT NULL,
  `fid` int(11) NOT NULL,
  KEY `uid` (`uid`,`fid`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_general_ci

Представляет собой таблицу зависимостей,
 где `uid` владелец
 где `fid` тот кто напрямую относится к владельцу
 если `uid`=1, и у него есть прямое отношение к пользователю, скажем, 3 (`fid`=3) то у пользователя 3 должна быть соответствующая запись, только наоборот, `uid`=3, `fid`=1

А запрос, приведённый выше (1ый пост), находит и выводит с помощью рекурсии все связи 4го уровня

Вот графическая запись того что делается..
1. user posted image 2. user posted image

1. Всё работает правильно
2. Выбор записей, SELECT `uid`, `fid`... работает правильно, с группировкой:
 uid  fid  
  4    3 
  5    7 
  5    8 

    Выбор кол-ва записей выводит несколько результатов работы COUNT, в то время когда нужен 1
COUNT( * )  
1 
2 

Проблемы:
  •  При 0 кол-ве (отсутствии записей 3го уровня), должно возвращать COUNT(*) -> 0 однако невозвращает ничего. (0 рядов)
  •  При наличии более одного пути к данной зависимости выводит их все, при простом выводе от этого спасает простая группировка, однако при выборе COUNT, насчитывает лишние пути..


Вот структура базы для приведённых примеров:
1.
Код

INSERT INTO `list` (`uid`, `fid`) VALUES 
(1, 2),
(2, 1),
(2, 4),
(3, 4),
(4, 2),
(4, 3);

2.
Код

INSERT INTO `list` (`uid`, `fid`) VALUES 
(1, 2),
(2, 1),
(2, 4),
(2, 5),
(2, 6),
(3, 4),
(4, 2),
(4, 3),
(5, 2),
(5, 7),
(5, 8),
(6, 2),
(6, 8),
(7, 5),
(8, 5),
(8, 6);


Уфф, надеюсь понятно обьяснил... smile 
PM MAIL   Вверх
muzer
Дата 28.10.2006, 22:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 387
Регистрация: 31.8.2006

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



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

Очередная пирамида? smile Впрочем неважно.
Я так понимаю для данного uid'а (%ID%) вам нужно вывести либо кол-во всех его рефералов третьего уровня, либо просто ввывести всех рефералов или что-то другое нужно?

1. У вас много избыточной информации, её можно сократить вдвое. Мы оставим например только записи вида uid=3 fid=1 для случая, когда юзер 3 зависим от 1.
2. Выбрать всех рефералов третьего уровня:
SELECT DISTINCT uid FROM list WHERE fid IN (SELECT DISTINCT uid FROM list WHERE fid IN (SELECT uid FROM list WHERE fid=%ID%));
3. Выбрать кол-во рефералов третьего уровня:
SELECT COUNT(DISTINCT uid) FROM list WHERE fid IN (SELECT DISTINCT uid FROM list WHERE fid IN (SELECT uid FROM list WHERE fid=%ID%));
4. Выбрать кол-во рефералов третьего уровня в разбивке по рефералам второго уровня:
SELECT fid,COUNT(uid) FROM list WHERE fid IN (SELECT DISTINCT uid FROM list WHERE fid IN (SELECT uid FROM list WHERE fid=%ID%)) GROUP BY fid;

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

Ну и ещё рекомендую пересмотреть структуру таблицы, если вам юудут нужны выборки такого вида. Почитайте про способы организации деревьев в базах данных.
PM WWW   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | MySQL | Следующая тема »


 




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


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

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