Отношения в MySQL и проблема QUERY - PullRequest
2 голосов
/ 26 января 2011

Привет, у меня два вопроса о MySQL и QUERIES.

  • Прежде всего мне хотелось бы знать, что делает diffrence при формировании запросов, если я устанавливаю отношения между таблицами в конструкторе phpmyadmins или нет -

  • И во-вторых, у меня есть 3 таблицы, и в моем запросе есть логическая ошибка. Кажется, что функция MAX () и GROUP BY не подходят друг другу: //

Так что если кто-нибудь знает, как решить мою проблему, поделитесь:)

И да, я использую MySQL 5.1.41, и я установил связи между таблицами

CREATE TABLE  `sandbox`.`videos` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`title` VARCHAR( 255 ) NOT NULL ,
`views` INT NOT NULL ,
`id_user` INT UNSIGNED NOT NULL ,
`id_type` INT UNSIGNED NOT NULL ,
INDEX (  `id_user` ,  `id_type` )
) ENGINE = INNODB;

id title views id_user id_type
------------------------------------
1 video1 50  1  1
2 video2 55  3  1
3 video3 100  2  3
4 video4 20  5  3
5 video5 62  4  5



CREATE TABLE  `sandbox`.`users` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`name` VARCHAR( 50 ) NOT NULL
) ENGINE = INNODB;

id name
-----------
1 adam
2 mike
3 chuck
4 walker
5 nancy



CREATE TABLE  `sandbox`.`types` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`name` VARCHAR( 50 ) NOT NULL
) ENGINE = INNODB;

id name
-------------
1 20 min
2 30 min
3 50 min
4 90 min
5 120 min

МОЙ ЗАПРОС:

SELECT videos.id, videos.title, MAX(videos.views) AS views, users.name AS user, types.name AS type 
FROM videos, users, types 
WHERE videos.id_user = users.id 
AND videos.id_type = types.id 
GROUP BY id_type  
ORDER BY id_type ASC
LIMIT 0 , 20;

QUERY RESULT:

id title views user type
------------------------------------
1 video1 55  adam 20 min
3 video3 100  mike 50 min
5 video5 62  walker 120 min

Функция GROUP BY группирует все записи по типу и получает данные только из первой записи в группе, но благодаря функции MAX () она копирует наибольшее значение из представлений и записывает его в первую запись в группе.

ХОТЕЛ РЕЗУЛЬТАТ:

id title views user type
------------------------------------
1 video2 55  chuck 20 min
3 video3 100  mike 50 min
5 video5 62  walker 120 min

Мне нужно, чтобы он выбирал все данные (в том числе заголовок и имя пользователя), а не только просматривал данные и группировал их по типу.

Спасибо за любую помощь:)

Ответы [ 2 ]

0 голосов
/ 26 января 2011

Во-первых, агрегатные функции, такие как MIN (), MAX, AVG (), COUNT (), SUM (), все будут использовать группу, если есть еще один столбец, такой как ваш пример ... знать, на каком разрыве рассматривать каждую группу ... (за исключением чего-то вроде SELECT MAX (Balance) из CustomerAccount - где это получает максимальный баланс независимо от того, кто или что).

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

SELECT 
      id_type, 
      max( views )
   from
      videos
   group by 
      id_type

Теперь, это дает мне внутреннюю предквалификацию ... для каждого типа видео, что было максимальным независимо от ID. Теперь, если есть проблемы с несколькими видео с одинаковым количеством, я также собираюсь использовать квалификатор MIN () для идентификатора в запросе второго уровня.

select 
      PreQuery.id_type,     
      min( v.ID ) as FirstVideoIDByType
   from
      ( SELECT 
             id_type, 
             max( views )
          from
             videos
          group by 
             id_type ) PreQuery,
      Videos v
   where 
      PreQuery.id_type = v.id_type
   group by 
      PreQuery.id_type

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

select 
      FinalVideo.*
   from
      ( select 
             PreQuery.id_type,     
             min( v.ID ) as FirstVideoIDByType
          from
             ( SELECT 
                    id_type, 
                    max( views )
                 from
                    videos
                 group by 
                    id_type ) PreQuery,
             Videos v
          where 
             PreQuery.id_type = v.id_type
          group by 
             PreQuery.id_type ) PreQuery2,
      Videos v2
   where
      PreQuery2.FirstVideoIDByType = v2.id
   order by
      v2.id_type
   limit
      0, 20;

Надеюсь, это прояснит, как и почему вещи работают так, как они ... Иногда сложно сломать элементы, чтобы получить то, что вы действительно хотите.

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

select 
      FinalVideo.*
   from
      ( SELECT 
              id_type, 
              max( views ) MaxViews
           from
              videos
           group by 
              id_type ) PreQuery,
       Videos v
    where 
           PreQuery.id_type = v.id_type
       and PreQuery.MaxViews = v.views
   order by
      v.id_type
   limit
      0, 20;
0 голосов
/ 26 января 2011

Попробуйте это не очень хороший метод, но все еще может удовлетворить ваши требования

SELECT *,MAX(result.views) AS views FROM(SELECT videos.id, videos.title, users.name AS user, types.name AS type 
    FROM videos, users, types 
    WHERE videos.id_user = users.id 
    AND videos.id_type = types.id ORDER BY videos.views DESC) AS `result` 
    GROUP BY `result`.`id_type`  
    ORDER BY  `result`.id_type ASC
    LIMIT 0 , 20;
...