Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 2010.08.27;
Скачать: [xml.tar.bz2];

Вниз

Подскажите SQL запрос   Найти похожие ветки 

 
d@nger   (2010-04-25 09:41) [0]

Здравствуйте! Имеется таблица (Firebird) с полем дата, и идентификатор клиента.

id           org_id                date
1             231              01.03.2010
2             231              02.04.2010
3             231              07.04.2010
4             115              15.04.2010
5             115              17.04.2010
6             205              20.04.2010
7             205              02.05.2010
...


нужно выбрать все записи за определенный месяц. Это я конечно сделал, но теперь нужно выбрать последнюю по дате запись каждого клиента, т.е из приведенного примера должны остаться записи 3, 5, 6. Я конечно могу это сделать в цикле проверяя каждую запись, но это будет не так эффективно если бы это сделать с помощью запроса. Возможно ли сделать такой запрос?


 
_Юрий ©   (2010-04-25 09:52) [1]

передать требуемую дату параметром?

select * from table where date=:p


 
d@nger   (2010-04-25 10:01) [2]


> _Юрий ©   (25.04.10 09:52) [1]
>
> передать требуемую дату параметром?


дата не известна, известен месяц. Нужно вытащить все записи за этот месяц и среди этих записей оставить только уникальные организации с последней датой...
select * from table where (date>="01.04.2010")and(date<="30.04.2010") вот это все на что у меня ума хватило... как теперь убрать повторные организации с меньшими дататами, а оставить только одну с наибольшей датой...


 
sniknik ©   (2010-04-25 10:23) [3]

> только уникальные организации с последней датой...
+ GROUP BY
и Max


 
d@nger   (2010-04-25 10:24) [4]

Урраа! Получилось... погуглил в инете... вот мое решение:

select org_id, max(call_date) from call_log group by call_log.org_id


 
Anatoly Podgoretsky ©   (2010-04-25 10:44) [5]

> d@nger  (25.04.2010 10:01:02)  [2]

Последняя, она же наибольшая - это MAX естественно.


 
d@nger   (2010-04-25 10:49) [6]

теперь не могу объединить эти 2 запроса в один


select * from table where (date>="01.04.2010")and(date<="30.04.2010")


select org_id, max(call_date) from call_log group by call_log.org_id


пишу так:
select id,call_date from call_log where (call_date>="01.04.2010")and(call_date<="30.04.2010")and
(id in (select id, max(call_date) from call_log group by call_log.org_id))


ошибка

Invalid token.
Dynamic SQL Error.
SQL error code = -104.
Invalid command.
count of column list and variable list do not match.


как правильно его записать?


 
d@nger   (2010-04-25 11:30) [7]

я снова погуглил...  решение следующее...
select org_id, max(call_date) from call_log
group by org_id having (max(call_date)>="01.04.2010")and(max(call_date)<="30.04.2010")


 
sniknik ©   (2010-04-25 12:30) [8]

> select org_id, max(call_date) from call_log
> group by org_id having (max(call_date)>="01.04.2010")and(max(call_date)<="30.04.2010")

индекс по полю org_id или call_date есть? если только по call_date то решение очень глупое...  если есть и по org_id, то просто слегка "туповатое".
группировать по всей таблице например 10 миллионов записей. и после обрезать до 10 нужных, это не то же самое, что отобрать 1000 за месяц и после сгруппировать их в нужные 10...


 
d@nger   (2010-04-26 06:50) [9]

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


 
d@nger   (2010-04-26 07:09) [10]

может уважаемый админ перенесет мою тему в раздел баз данных?...
может кто нибудь подскажет что нибудь.. оптимально ли делать следующим образом
1) создавать сначала представление,
2) потом делать группировку в этом представлении,
3 )формировать отчет на основе полученных данных,
4) удалить представление

или все таки возможно как то обойтись без представления?


 
sniknik ©   (2010-04-26 07:44) [11]

все можно, нужно только немного изучить синтаксис sql, а не искать готовое по инету, понимать что пишешь...
а то до смешного доходит, не мочь сделать в уже готовом легкую коррекцию, поменять оператор и изменить синтаксис в соответствии с его правилами.

p.s. самое место теме здесь. запросы с where описывают на втором, или третьем занятии в книгах типа "sql для чайников", сразу после введения... группировки попозже, но с ними у тебя проблем вроде нет.


 
d@nger   (2010-04-26 08:14) [12]

вымучил я все таки этот запрос...

select org_id, max(call_date) from call_log where call_date between "01.05.2010" and "30.05.2010"
group by org_id


всем спасибо, что направили на путь истинный.. ))))


 
Anatoly Podgoretsky ©   (2010-04-26 08:44) [13]


> может уважаемый админ перенесет мою тему в раздел баз данных?
> ...

С какой стати, твой вопрос вообще не имеет отношения к програмированию в Дельфи, тебе нужно в форум по FB, а здесь такого нет. Наиболее близкая конференция это Общая.


 
d@nger   (2010-04-26 09:03) [14]

придется мне опять поднять эту тему...

кроме полей org_id, и call_date? нужно вытащить еще 2 текстовых поля, но в этом случае скрипт не работает, НО если дабавить эти текстовые поля в group by, ошибки нет, но результат не группируется по org_id... как быть в этом случае?


 
sniknik ©   (2010-04-26 09:30) [15]

> но результат не группируется по org_id...
эк, я тебя "сглазил"...
> но с ними у тебя проблем вроде нет.

> как быть в этом случае?
читать четвертый раздел "sql для чайников" по "group by". и внимательно смотреть на call_date в запросе.


 
Дмитрий С ©   (2010-04-26 09:41) [16]

тут поможет уловка с CONCAT

SELECT * FROM `call_log` WHERE `id` IN (
   SELECT
       CAST(SUBSTRING(MAX(CONCAT(LPAD(`date`,20,0), `id`)), 21) AS INT)
   FROM
       `call_log`
   WHERE
       `date` between "01.05.2010" and "30.05.2010"
   GROUP BY `org_id`
)

Это на MYSQL. На FB переведешь сам


 
d@nger   (2010-04-26 10:42) [17]

что то не получается у меня ничего.. склоняюсь к варианту с представлениями..


 
d@nger   (2010-04-26 10:43) [18]

LPAD(`date`,20,0), `id`) может здесь нужнобыло использовать RPAD ?


 
test ©   (2010-04-26 11:08) [19]

ИМХО как то так.

select a.org_id, max(a.call_date) from call_log a
left join table b on ((date>="01.04.2010")and(date<="30.04.2010")) and a.org_id = b.id
group by a.org_id


 
sniknik ©   (2010-04-26 11:17) [20]

ужас какой...

простейший вариант это включить поля в агрегатных функциях, аналогично call_date (ведь он то тебе не мешает группировать по org_id)
но лучше конечно так (надеюсь id  это ключ, и авто инкремент (ну аналог его в FB), и еще надеюсь даты в строках воспринимаются правильно... хотя в любом случае советую параметры)

select org_id, call_date, еще 2 текстовых поля from call_log
WHERE id IN
(select max(id) from call_log where call_date between "01.05.2010" and "30.05.2010" group by org_id)


 
test ©   (2010-04-26 11:20) [21]

sniknik ©   (26.04.10 11:17) [20]
Oracle))


 
Дмитрий С ©   (2010-04-26 11:20) [22]


> sniknik ©

В условиях нет факта, что id и call_date одновременно возрастают.


 
boriskb ©   (2010-04-26 11:26) [23]

Самое время задуматься: "От инета больше вреда или пользы?"


 
d@nger   (2010-04-26 11:29) [24]


> test ©   (26.04.10 11:08) [19]
>
> ИМХО как то так.
>
> select a.org_id, max(a.call_date) from call_log a
> left join table b on ((date>="01.04.2010")and(date<="30.
> 04.2010")) and a.org_id = b.id
> group by a.org_id


этот вариант не дает доступа к тектовым полям таблицы call_log, в принципе он вообще ничем не отличается от моего варианта...


 
d@nger   (2010-04-26 11:31) [25]


> Дмитрий С ©   (26.04.10 11:20) [22]
>
>
> > sniknik ©
>
> В условиях нет факта, что id и call_date одновременно возрастают.
>


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


 
test ©   (2010-04-26 11:35) [26]

d@nger   (26.04.10 11:29) [24]
Какой доступ нужен?


 
d@nger   (2010-04-26 11:37) [27]

у меня такая мысль возникла, если группировка работает с агрегатными функциями, нельзя ли написать свою агрегатную функцию, которая ничего не делает, а возвращает то же значение что в него и посупило,  например: TXT("это текст") = это текст .... т.е сделав такю функцию мы сможем ее включить в параметры select и вывести отдельным столбцом


 
test ©   (2010-04-26 11:37) [28]

select c.* from call_log
left join
(select a.org_id, max(a.call_date) from call_log a
left join table b on ((date>="01.04.2010")and(date<="30.04.2010")) and a.org_id = b.id
group by a.org_id) b on c.id = b.id


 
test ©   (2010-04-26 11:39) [29]

d@nger   (26.04.10 11:37) [27]
Все уже украдено до нас))

select c.*, "это мы напишем тута","а это мы напишем в тама" from call_log с


 
d@nger   (2010-04-26 11:39) [30]


> test ©   (26.04.10 11:35) [26]
>
> d@nger   (26.04.10 11:29) [24]
> Какой доступ нужен?


помимо ORG_ID и CALL_DATE, есть текстовые поля ORG_NAME и TEXT, которые тоже нужно отобразить в результате запроса . если эти поля включить в select то придется и в группировку их включить, что повлияет на результат группировки


 
test ©   (2010-04-26 11:41) [31]

d@nger   (26.04.10 11:39) [30]
Проверь запрос из поста 28.


 
d@nger   (2010-04-26 11:45) [32]


> test ©   (26.04.10 11:41) [31]
>
> d@nger   (26.04.10 11:39) [30]
> Проверь запрос из поста 28.


проверяю....
select * from call_log c
left join
(select a.org_id, max(a.call_date) from call_log a
left join clients b on ((call_date>="01.04.2010")and(call_date<="30.04.2010")) and a.org_id = b.id
group by a.org_id) b on c.id = b.id


ошибка...
Invalid token.
Dynamic SQL Error.
SQL error code = -104.
Invalid command.
no column name specified for column number 2 in derived table B.


 
test ©   (2010-04-26 11:52) [33]

select * from call_log c
left join
(select a.org_id, max(a.call_date) max_date from call_log a
left join clients b on ((call_date>="01.04.2010")and(call_date<="30.04.2010")) and a.org_id = b.id
group by a.org_id) b on c.id = b.id


Ну назови поле как нибудь например max_date он же об этом говорит


 
d@nger   (2010-04-26 11:55) [34]


> Ну назови поле как нибудь например max_date он же об этом
> говорит

я не знаю куда его воткнуть... я sql плохо пока знаю


 
test ©   (2010-04-26 11:58) [35]

я привел же написал куда и где

select * from call_log c
left join
(select a.org_id, max(a.call_date) max_date from call_log a
left join clients b on ((call_date>="01.04.2010")and(call_date<="30.04.2010")) and a.org_id = b.id
group by a.org_id) b on c.id = b.id


 
d@nger   (2010-04-26 12:03) [36]

сорри.. не увидел...


 
d@nger   (2010-04-26 12:11) [37]

теперь другая ошибка ...
select * from call_log c
left join
(select a.org_id, max(a.call_date) max_date from call_log a
left join clients b on ((call_date>="01.04.2010")and(call_date<="30.04.2010")) and a.org_id = b.id
group by a.org_id) b on c.id = b.id


ошибка ...

> Column does not belong to referenced table.
> Dynamic SQL Error.
> SQL error code = -206.
> Column unknown.
> B.ID.
> At line 5, column 34.


 
sniknik ©   (2010-04-26 12:17) [38]

> у меня такая мысль возникла, если группировка работает с агрегатными функциями, нельзя ли написать свою агрегатную функцию
читай внимательно, и писать не будет ничего нужно...
> простейший вариант это включить поля в агрегатных функциях, аналогично call_date (ведь он то тебе не мешает группировать по org_id)


 
test ©   (2010-04-26 12:17) [39]

ошибка означает нет такого поля
скорее всего это он про
c.id = b.id
b.id должно быть b.org_id
c.id нужно смотреть в названиях полей таблицы

в select * from тожке лучше указать что тебе нужно select c.* from, а то он тебе весь набор вытащит.

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

Надо поля смотреть, может быть у тебя таких и нету в таблице.


 
d@nger   (2010-04-26 12:33) [40]

структура таблиц следующая:
таблица call_log
ID     - ключ
ORG_ID - ключ организации клиента из таблицы clients.id
CALL_DATE - дата
TEXT - текст
ORG_NAME - текст

в таблице clients много полей... но поле ID точно есть... тоже ключевое...



Страницы: 1 2 вся ветка

Форум: "Прочее";
Текущий архив: 2010.08.27;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.55 MB
Время: 0.063 c
6-1221941736
WBcodderW
2008-09-21 00:15
2010.08.27
WebBrowser, формы и JS кнопки


3-1240576232
Гарик
2009-04-24 16:30
2010.08.27
Пользователи в Oracle


2-1272448331
Sergey2
2010-04-28 13:52
2010.08.27
MultiSelect в ComboBox


2-1268475991
Fr
2010-03-13 13:26
2010.08.27
Сохранение TChart


2-1273504909
Тим
2010-05-10 19:21
2010.08.27
сортировка в stringlist





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский