Logo Море(!) аналитической информации!
IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware
Архив форумов ЦИТФорума
Море(!) вопросов - Море(!) ответов
 
 FAQFAQ   ПоискПоиск   ПользователиПользователи   ГруппыГруппы   РегистрацияРегистрация 
 ПрофильПрофиль   Войти и проверить личные сообщенияВойти и проверить личные сообщения   ВходВход 
Как правильно задавать вопросы

Вопрос по SQL

 
Перейти:  
Этот форум закрыт, вы не можете писать новые сообщения и редактировать старые.   Эта тема закрыта, вы не можете писать ответы и редактировать сообщения.    Список форумов Архив форумов ЦИТФорума -> Базы данных
Предыдущая тема :: Следующая тема  
Автор Сообщение
MaximusX



Зарегистрирован: 10.02.2004
Сообщения: 12

СообщениеДобавлено: Вт Фев 10 2004 06:02    Заголовок сообщения: Вопрос по SQL Ответить с цитатой

Имеется следующий запрос:

SELECT
C.PrimaryKeyC,
max(A.SomeField)
FROM
A, B, C
WHERE
A.PrimaryKeyB = B.PrimaryKeyB AND
B.PrimaryKeyC = C.PrimaryKeyC
GROUP BY
C.PrimaryKeyC

Необходимо, помимо максимального значения поля SomeField из таблицы A вернуть еще и значение ее первичного ключа, относящегося к этой записи, т.е. A.PrimaryKey. Все услажняестя тем, что поле C.PrimaryKey выбирать нужно обязательно.
Пожалуйста, подскажите как это можно сделать.
Вернуться к началу
Посмотреть профиль Отправить личное сообщение Отправить e-mail
Antidote
Гость





СообщениеДобавлено: Вт Фев 10 2004 11:23    Заголовок сообщения: ответ Ответить с цитатой

подзапросом
предвижу вопрос как...на эту тему тьма книжек, а уж в инете....
Вернуться к началу
Сарсенов



Зарегистрирован: 27.01.2004
Сообщения: 10

СообщениеДобавлено: Ср Фев 11 2004 06:40    Заголовок сообщения: Вопрос Ответить с цитатой

Из таблицы A надо вернуть A.PrimaryKeyA?
Вернуться к началу
Посмотреть профиль Отправить личное сообщение Отправить e-mail
MaximusX



Зарегистрирован: 10.02.2004
Сообщения: 12

СообщениеДобавлено: Чт Фев 12 2004 05:16    Заголовок сообщения: Ответить с цитатой

2Antidote:
То что подзапросом это и ежу понятно. А вот чем бестолку говорить взял бы и написал. Насчет книжок: времени на решение этой проблемы уйдет намного больше (надо же аж целую книженцию почитать, полистать; а может и не одну; в инете тоже долго рыться). Я и сам знаю, что в книжках такого полно; если не хочешь, не отвечай, а вот пустые советы давать и дурак может.

2Сарсенов:
Абсолютно верно. Нужно выбрать еще и ключ A.PrimaryKeyA соответсвенно из таблицы A.
Вернуться к началу
Посмотреть профиль Отправить личное сообщение Отправить e-mail
Сарсенов



Зарегистрирован: 27.01.2004
Сообщения: 10

СообщениеДобавлено: Чт Фев 12 2004 06:51    Заголовок сообщения: Ответ Ответить с цитатой

Не хочу тебя расстраивать, но если я правильно понял твою постановку задачи, то это невозможно.
Ты ведь находишь максимальные значения поля A.SomeField в наборах
строк (группировках) с одинаковыми значениеми поля C.PrimaryKeyC.
А так как ты задаешь условия:
"WHERE
A.PrimaryKeyB = B.PrimaryKeyB AND
B.PrimaryKeyC = C.PrimaryKeyC",
то можно говорить, что ты находишь максимальные значения поля A.SomeField в наборах строк (группировках) с одинаковыми значениями поля A.PrimaryKeyB.
Т.к поле PrimaryKeyA в таблице A, по определению, обязано иметь уникальные значения, а поле PrimaryKeyB в таблице A совсем не обязано иметь уникальные значения, то отсюда возникает логическая несовместимость.
Если я что-то не так понял, то напиши.
Возможно, я не до конца понял условия твоей задачи.
Вернуться к началу
Посмотреть профиль Отправить личное сообщение Отправить e-mail
wildwind



Зарегистрирован: 03.02.2004
Сообщения: 268
Откуда: Москва

СообщениеДобавлено: Чт Фев 12 2004 14:31    Заголовок сообщения: Ответить с цитатой

Код:
select C.PrimaryKeyC,
       A.PrimaryKeyA,
       A.SomeField
  from A, B, (
         select B.PrimaryKeyC,
                max(A.SomeField) as SomeFieldMax
           from A, B
          where A.PrimaryKeyB = B.PrimaryKeyB
          group by B.PrimaryKeyC
       ) C
 where A.PrimaryKeyB = B.PrimaryKeyB
   and B.PrimaryKeyC = C.PrimaryKeyC
   and A.SomeField = C.SomeFieldMax

На самом деле сложность в том, что записей с максимальным значением SomeField может быть несколько для каждого PrimaryKeyC.
Вернуться к началу
Посмотреть профиль Отправить личное сообщение Отправить e-mail
MaximusX



Зарегистрирован: 10.02.2004
Сообщения: 12

СообщениеДобавлено: Пт Фев 13 2004 08:01    Заголовок сообщения: Ответить с цитатой

2wildwind:
Спасибо за помощь!!! Работает почти как надо, только если для C.PrimaryKeyC существует несколько записей с одинаковыми полями A.SomeField, значение которых максимально, то в результирующем запросе будет ровно столько записей (один в один) сколько этих максимальных, поэтому еще нужно добавить distinct в самый первый селект. (На самом деле запрос у меня отрабатывает для конкретной записи таблицы C, т.е. в последнем условии есть еще
Код:
and С.PrimaryKetC = SomeValue
, и поэтому дублирование не охота видеть; с distinct'ом работает так как я хотел)

2Сарсенов:
Решение то оказывается есть ! (и довольно интересное) Скорее всего была тобой немного неверно понята постановка задачи. Но если хочется, то разобравшись в запросе, ее можно понять.
Вернуться к началу
Посмотреть профиль Отправить личное сообщение Отправить e-mail
Сарсенов



Зарегистрирован: 27.01.2004
Сообщения: 10

СообщениеДобавлено: Пт Фев 13 2004 09:14    Заголовок сообщения: Снимаю шляпу Ответить с цитатой

Снимаю перед тобой шляпу, wildwind!
Ты нашел решение задачи, которую я посчитал нерешаемой.
Laughing
Ты крут Surprised
Вернуться к началу
Посмотреть профиль Отправить личное сообщение Отправить e-mail
Гость






СообщениеДобавлено: Пт Фев 13 2004 11:39    Заголовок сообщения: Ответить с цитатой

2 MaximusX
Добавив distinct, ты потеряешь PrimaryKeyA, то есть должен будешь убрать его из списка, иначе distinct не даст эффекта. Но в условии задачи ты настаивал, что PrimaryKeyA нужен тебе обязательно! Фактически, тебе нужны не все A, а любой A с максимальным SomeField, так что ли? А тут еще и условие на PrimaryKeyC, тогда все еще проще.
Код:
select A.PrimaryKeyA,
       A.SomeField
  from A, B
 where A.PrimaryKeyB = B.PrimaryKeyB
   and B.PrimaryKeyC = :PKC
   and A.SomeField = ( select max(A.SomeField)
                         from A, B
                        where A.PrimaryKeyB = B.PrimaryKeyB
                          and B.PrimaryKeyC = :PKC )

Выбрав из этого запроса только первую строчку, получишь тот самый любой A. Выбрав остальные, получишь все.

Но это уже другая задача! В следующий раз формулируй условия яснее.

2 Сарсенов:
Я не крут, просто задача была не совсем корректно поставлена, что и заводило в тупик.
Вернуться к началу
wildwind



Зарегистрирован: 03.02.2004
Сообщения: 268
Откуда: Москва

СообщениеДобавлено: Пт Фев 13 2004 11:41    Заголовок сообщения: Ответить с цитатой

Это был я незарегистрироваанный... /\
Вернуться к началу
Посмотреть профиль Отправить личное сообщение Отправить e-mail
MaximusX



Зарегистрирован: 10.02.2004
Сообщения: 12

СообщениеДобавлено: Пн Фев 16 2004 05:55    Заголовок сообщения: Ответить с цитатой

2wildwind:
Запрос с distinct работает как надо, ключ A.PrimaryKey не теряется...
что имелось ввиду под этим не пойму... Последний запрос для моей задачи не годится (хотя он и простой). Задачу свою я сразу не описал полностью, так как, усложнив сначала, мог бы запутать мозги и отпугнуть добрых советчиков... Суть задачи в том же как я и описал вначале (хотя всем кажется, что я не точно сформулировал) + система построена так, что при выполнении запроса она добавляет условие на ключ C.Premises_ID (and С.PrimaryKetC = SomeValue) своими силами и я ручками это не пишу, так что последний запрос в данном случае не приемлем. А вот насчет distinct если можно поподробнее...
Вернуться к началу
Посмотреть профиль Отправить личное сообщение Отправить e-mail
wildwind



Зарегистрирован: 03.02.2004
Сообщения: 268
Откуда: Москва

СообщениеДобавлено: Пн Фев 16 2004 12:12    Заголовок сообщения: Ответить с цитатой

Что делает distinct? Убирает из результирующего множества одинаковые записи. Одинаковые - это значит ВСЕ поля совпадают. Допустим select без distinct (первый вариант) вернул:
Код:
PrimaryKeyC  PrimaryKeyA  SomeField
----------- ------------ ----------
         12            1        444
         12            2        444
         12            3        444

Эти три записи РАЗНЫЕ, и distinct не превратит их волшебным образом в одну. Можно убрать из select'а столбец PrimaryKeyA и добавить distinct, тогда для каждого PrimaryKeyC вернется не более одной записи. Но тогда ты не узнаешь, какие именно записи в A имеют максимальное значение SomeField. Это я имел в виду под потерей PrimaryKeyA.

____________________


Второй вариант будет работать быстрее, выбирая из таблиц только необходимые данные, а в первом варианте внутренний select будет вычислять max(A.SomeField) для всех PrimaryKeyC. Хотя, если оптимизатор в СУБД достаточно умный, то возможно он это поправит. Кстати, на чем это все у тебя жужжит, если не секрет?
Вернуться к началу
Посмотреть профиль Отправить личное сообщение Отправить e-mail
MaximusX



Зарегистрирован: 10.02.2004
Сообщения: 12

СообщениеДобавлено: Пн Фев 16 2004 14:10    Заголовок сообщения: Ответить с цитатой

2wildwind:
Как работает distinct я знаю, и запрос с ним у меня отрабатывает, потому что в моем случае A.PrimaryKeyA для всех записей будет один.
Это связано с тем, что для одной записи в таблице С имеется не более одной записи в таблице B, для которой имеется несколько записей в таблице A; смысл такой, что в моем случае A.PrimaryKeyA один.
Вообще-то проблема решена...Еще раз все спасибо !!!
Тема закрыта.
Вернуться к началу
Посмотреть профиль Отправить личное сообщение Отправить e-mail
Показать сообщения:   
Этот форум закрыт, вы не можете писать новые сообщения и редактировать старые.   Эта тема закрыта, вы не можете писать ответы и редактировать сообщения.    Список форумов Архив форумов ЦИТФорума -> Базы данных Часовой пояс: GMT + 3
Страница 1 из 1

 
Перейти:  
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах


Powered by phpBB © 2001, 2002 phpBB Group
Русская поддержка phpBB

 

IT-консалтинг Software Engineering Программирование СУБД Безопасность Internet Сети Операционные системы Hardware

Информация для рекламодателей PR-акции, размещение рекламы — adv@citforum.ru,
тел. +7 495 6608306, ICQ 232284597
Пресс-релизы — pr@citforum.ru
Послать комментарий
Информация для авторов
This Web server launched on February 24, 1997
Copyright © 1997-2000 CIT, © 2001-2006 CIT Forum
Внимание! Любой из материалов, опубликованных на этом сервере, не может быть воспроизведен в какой бы то ни было форме и какими бы то ни было средствами без письменного разрешения владельцев авторских прав. Подробнее...