информационная безопасность
без паники и всерьез
 подробно о проектеRambler's Top100
Все любят медПортрет посетителяЗа кого нас держат?
BugTraq.Ru
Русский BugTraq
 Анализ криптографических сетевых... 
 Модель надежности двухузлового... 
 Специальные марковские модели надежности... 
 Столлман возвращается в FSF 
 The Great Suspender предположительно... 
 Десятилетняя уязвимость в sudo 
главная обзор RSN блог библиотека закон бред форум dnet о проекте
bugtraq.ru / форум / web building
Имя Пароль
ФОРУМ
если вы видите этот текст, отключите в настройках форума использование JavaScript
регистрация





Легенда:
  новое сообщение
  закрытая нитка
  новое сообщение
  в закрытой нитке
  старое сообщение
  • Напоминаю, что масса вопросов по функционированию форума снимается после прочтения его описания.
  • Новичкам также крайне полезно ознакомиться с данным документом.
Помогите написать SQL запрос 22.07.08 11:17  
Автор: Vedrus <Serokhvostov Anton> Статус: Member
Отредактировано 22.07.08 11:30  Количество правок: 3
<"чистая" ссылка> <обсуждение закрыто>
Столкнулся с такой задачей: Выбрать все title из Fancy и для каждого из них выбрать минимальную дату из Sess.

Fancy:
id_Fancy
title

Sess:
id_Sess
Fancy
date

Лучшее, что получилось – это
$res = mysql_query("SELECT f.id_Fancy, f.title, s.date FROM Sess as s RIGHT JOIN Fancy as f ON f.id_Fancy=s.Fancy");

Этот запрос выводит почти то, что нужно. «Почти» потому что он для каждой даты из Sess выводит отдельную строку, а нужно чтобы была одна.

Попробовал разобраться с оператором DISTINCT (ставил его перед f.id_Fancy), но эффекта не дало.

Такой запрос вообще ничего не вворачивает
$res = mysql_query("SELECT f.id_Fancy, f.title, s.date FROM Sess as s RIGHT JOIN Fancy as f ON f.id_Fancy=s.Fancy WHERE (s.date = (SELECT MAX(s.date) FROM s WHERE f.id_Fancy=s.Fancy))");
Правильно так: 22.07.08 12:01  
Автор: Den <Denis> Статус: The Elderman
Отредактировано 22.07.08 12:02  Количество правок: 1
<"чистая" ссылка> <обсуждение закрыто>
Правильно так:
SELECT DISTINCT f.id_Fancy, f.title, MIN(s.date)
  FROM Sess as s
    RIGHT JOIN Fancy as f ON f.id_Fancy=s.Fancy
  GROUP BY id_Fancy, title

---
Den, то что нужно. Огроменное спасибо! 22.07.08 13:22  
Автор: Vedrus <Serokhvostov Anton> Статус: Member
<"чистая" ссылка> <обсуждение закрыто>
Остальным тоже спасибо, но решение Den’а для меня более приемлемо.

PS. В документации по SQL вычитал, что лучше использовать JOIN, чем подзапросы (накладных расходов меньше), т.к. при использовании JOIN SQL-сервер задействует свои механизмы оптимизации.
А не проще ли развернуть запрос? Сначала выбрать fancy, (MaxDate), потом слить их с таблицей имен? 22.07.08 11:56  
Автор: kstati <Евгений Борисов> Статус: Elderman
Отредактировано 22.07.08 12:07  Количество правок: 2
<"чистая" ссылка> <обсуждение закрыто>
SELECT s.Fancy, MIN(s.date), f.title
FROM `sess` s
RIGHT JOIN Fancy F On f.id_fancy=s.Fancy
Group by s.Fancy

Да и нагрузка на БД меньше:

-------------------
EXPLAIN SELECT t.title, min( t.date )
FROM ( SELECT f.title, s.date FROM fancy f JOIN sess s ON s.fancy = f.id_fancy )t GROUP BY t.title

d select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 28 Using temporary; Using filesort
2 DERIVED s ALL NULL NULL NULL NULL 28
2 DERIVED f ALL PRIMARY NULL NULL NULL 4 Using where

-----------------

SELECT s.Fancy, MIN(s.date), f.title FROM `sess` s
RIGHT JOIN Fancy F On f.id_fancy=s.Fancy Group by s.Fancy
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE F ALL NULL NULL NULL NULL 5 Using temporary; Using filesort
1 SIMPLE s ALL NULL NULL NULL NULL 28


> Столкнулся с такой задачей: Выбрать все title из
> Fancy и для каждого из них выбрать минимальную дату из
> Sess.

>
> Fancy:
> id_Fancy
> title
>
> Sess:
> id_Sess
> Fancy
> date
>
> Лучшее, что получилось – это
> $res = mysql_query("SELECT f.id_Fancy, f.title,
> s.date FROM Sess as s RIGHT JOIN Fancy as f ON
> f.id_Fancy=s.Fancy");

>
> Этот запрос выводит почти то, что нужно. «Почти» потому что
> он для каждой даты из Sess выводит отдельную строку, а
> нужно чтобы была одна.
>
> Попробовал разобраться с оператором DISTINCT (ставил его
> перед f.id_Fancy), но эффекта не дало.
>
> Такой запрос вообще ничего не вворачивает
> $res = mysql_query("SELECT f.id_Fancy, f.title,
> s.date FROM Sess as s RIGHT JOIN Fancy as f ON
> f.id_Fancy=s.Fancy WHERE (s.date = (SELECT MAX(s.date) FROM
> s WHERE f.id_Fancy=s.Fancy))");
Нет ничего хуже связывания таблиц на клиенте. 22.07.08 12:57  
Автор: Den <Denis> Статус: The Elderman
<"чистая" ссылка> <обсуждение закрыто>
если можно подзапросы делать то так: 22.07.08 11:54  
Автор: i1 Статус: Незарегистрированный пользователь
Отредактировано 22.07.08 11:55  Количество правок: 1
<"чистая" ссылка> <обсуждение закрыто>
> Столкнулся с такой задачей: Выбрать все title из
> Fancy и для каждого из них выбрать минимальную дату из
> Sess.

>
> Fancy:
> id_Fancy
> title
>
> Sess:
> id_Sess
> Fancy
> date
>
> Лучшее, что получилось – это
> $res = mysql_query("SELECT f.id_Fancy, f.title,
> s.date FROM Sess as s RIGHT JOIN Fancy as f ON
> f.id_Fancy=s.Fancy");

>
> Этот запрос выводит почти то, что нужно. «Почти» потому что
> он для каждой даты из Sess выводит отдельную строку, а
> нужно чтобы была одна.
>
> Попробовал разобраться с оператором DISTINCT (ставил его
> перед f.id_Fancy), но эффекта не дало.
>
> Такой запрос вообще ничего не вворачивает
> $res = mysql_query("SELECT f.id_Fancy, f.title,
> s.date FROM Sess as s RIGHT JOIN Fancy as f ON
> f.id_Fancy=s.Fancy WHERE (s.date = (SELECT MAX(s.date) FROM
> s WHERE f.id_Fancy=s.Fancy))");


если можно подзапросы делать то так:

select t.title, min(t.date)
from (select f.title, s.date from fancy f join sess s on s.fancy = f.id_fancy) t
group by t.title
1






Rambler's Top100
Рейтинг@Mail.ru


  Copyright © 2001-2021 Dmitry Leonov   Page build time: 0 s   Design: Vadim Derkach