Предыдущая тема :: Следующая тема |
Автор |
Сообщение |
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 выбирать нужно обязательно.
Пожалуйста, подскажите как это можно сделать. |
|
Вернуться к началу |
|
|
Antidote Гость
|
Добавлено: Вт Фев 10 2004 11:23 Заголовок сообщения: ответ |
|
|
подзапросом
предвижу вопрос как...на эту тему тьма книжек, а уж в инете.... |
|
Вернуться к началу |
|
|
Сарсенов
Зарегистрирован: 27.01.2004 Сообщения: 10
|
Добавлено: Ср Фев 11 2004 06:40 Заголовок сообщения: Вопрос |
|
|
Из таблицы A надо вернуть A.PrimaryKeyA? |
|
Вернуться к началу |
|
|
MaximusX
Зарегистрирован: 10.02.2004 Сообщения: 12
|
Добавлено: Чт Фев 12 2004 05:16 Заголовок сообщения: |
|
|
2Antidote:
То что подзапросом это и ежу понятно. А вот чем бестолку говорить взял бы и написал. Насчет книжок: времени на решение этой проблемы уйдет намного больше (надо же аж целую книженцию почитать, полистать; а может и не одну; в инете тоже долго рыться). Я и сам знаю, что в книжках такого полно; если не хочешь, не отвечай, а вот пустые советы давать и дурак может.
2Сарсенов:
Абсолютно верно. Нужно выбрать еще и ключ A.PrimaryKeyA соответсвенно из таблицы A. |
|
Вернуться к началу |
|
|
Сарсенов
Зарегистрирован: 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 совсем не обязано иметь уникальные значения, то отсюда возникает логическая несовместимость.
Если я что-то не так понял, то напиши.
Возможно, я не до конца понял условия твоей задачи. |
|
Вернуться к началу |
|
|
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. |
|
Вернуться к началу |
|
|
MaximusX
Зарегистрирован: 10.02.2004 Сообщения: 12
|
Добавлено: Пт Фев 13 2004 08:01 Заголовок сообщения: |
|
|
2wildwind:
Спасибо за помощь!!! Работает почти как надо, только если для C.PrimaryKeyC существует несколько записей с одинаковыми полями A.SomeField, значение которых максимально, то в результирующем запросе будет ровно столько записей (один в один) сколько этих максимальных, поэтому еще нужно добавить distinct в самый первый селект. (На самом деле запрос у меня отрабатывает для конкретной записи таблицы C, т.е. в последнем условии есть еще Код: | and С.PrimaryKetC = SomeValue | , и поэтому дублирование не охота видеть; с distinct'ом работает так как я хотел)
2Сарсенов:
Решение то оказывается есть ! (и довольно интересное) Скорее всего была тобой немного неверно понята постановка задачи. Но если хочется, то разобравшись в запросе, ее можно понять. |
|
Вернуться к началу |
|
|
Сарсенов
Зарегистрирован: 27.01.2004 Сообщения: 10
|
Добавлено: Пт Фев 13 2004 09:14 Заголовок сообщения: Снимаю шляпу |
|
|
Снимаю перед тобой шляпу, wildwind!
Ты нашел решение задачи, которую я посчитал нерешаемой.
Ты крут |
|
Вернуться к началу |
|
|
Гость
|
Добавлено: Пт Фев 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 Заголовок сообщения: |
|
|
Это был я незарегистрироваанный... /\ |
|
Вернуться к началу |
|
|
MaximusX
Зарегистрирован: 10.02.2004 Сообщения: 12
|
Добавлено: Пн Фев 16 2004 05:55 Заголовок сообщения: |
|
|
2wildwind:
Запрос с distinct работает как надо, ключ A.PrimaryKey не теряется...
что имелось ввиду под этим не пойму... Последний запрос для моей задачи не годится (хотя он и простой). Задачу свою я сразу не описал полностью, так как, усложнив сначала, мог бы запутать мозги и отпугнуть добрых советчиков... Суть задачи в том же как я и описал вначале (хотя всем кажется, что я не точно сформулировал) + система построена так, что при выполнении запроса она добавляет условие на ключ C.Premises_ID (and С.PrimaryKetC = SomeValue) своими силами и я ручками это не пишу, так что последний запрос в данном случае не приемлем. А вот насчет distinct если можно поподробнее... |
|
Вернуться к началу |
|
|
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. Хотя, если оптимизатор в СУБД достаточно умный, то возможно он это поправит. Кстати, на чем это все у тебя жужжит, если не секрет? |
|
Вернуться к началу |
|
|
MaximusX
Зарегистрирован: 10.02.2004 Сообщения: 12
|
Добавлено: Пн Фев 16 2004 14:10 Заголовок сообщения: |
|
|
2wildwind:
Как работает distinct я знаю, и запрос с ним у меня отрабатывает, потому что в моем случае A.PrimaryKeyA для всех записей будет один.
Это связано с тем, что для одной записи в таблице С имеется не более одной записи в таблице B, для которой имеется несколько записей в таблице A; смысл такой, что в моем случае A.PrimaryKeyA один.
Вообще-то проблема решена...Еще раз все спасибо !!!
Тема закрыта. |
|
Вернуться к началу |
|
|
|