Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

SQL Запрос [IB6.x]


Страницы:   1 2

REA ©   (2005-02-10 11:26:00) 

Добрый день. Помогите плз составить SQL запросик:
Есть таблица T1 с полем N:
N
1
2
3
и таблица T2 c полями N, Time, X1
N Time   X1
1 13:00  aaa
1 14:00  bbb
2 12:00  ccc
2 15:00  ddd

Нужно получить максимальное время для каждого N:
1 14:00 bbb
2 15:00 ddd
Если будет и "3, NULL, NULL" то тоже пойдет


REA   (2005-02-11 17:27:00) [1]

Thanx. WELLID просто часть ключа (номер скважины). После включения WELLID (а без него PLAN NATURAL) получилось IR 2280 и 6, а виде [22] на тех же данных 380 + 30.

Suspend в IB есть? Пока обходился без хранимых процедур.

PS: Это как раз и есть резервуары, но для бурового раствора.


Johnmen   (2005-02-11 14:45:00) [2]

Примерно так, хотя непонятно, что есть WELLID и каким оно боком:
SELECT T1.TANKNO,
      T1.TANKGEOMETRY,
      T2.TANKACTIVE
FROM Tanks T1, TanksLog T2
WHERE (T1.TANKNO=T2.TANKNO) AND(T2.WELLID=1) AND
 (T2.LOGTIME=(SELECT MAX(T3.LOGTIME)
              FROM TanksLog T3
              WHERE (T3.TANKNO=T2.TANKNO) {возможно AND T3.WELLID=1}))


PS
Вспомнил, как писал для "Транснефти". Учет резервуаров(танков) хранения нефти, их параметры, обслуживание и дефектоскопия...:)


ЮЮ   (2005-02-11 13:38:00) [3]

Suspend - это их области хранимых процедур, т.е. вернет с сервера запись клиенту

logGrouped - это возможно только на SQL - использовать запрос как таблицу в операциях связи (logGrouped - алиас подзапроса)


REA   (2005-02-11 13:34:00) [4]

2Johnmen:
Переформулирую задачу:
Есть таблица Tanks c полями +WELLID, +TANKNO, GEOMETRY и таблица TanksLog с полями +WELLID, +TANKNO, +LOGTIME, TANKACTIVE
нужно получить выборку с полями
TANKNO, TANKGEOMETRY, TANKACTIVE для WELLID=1, и всеми (уникальными)TanksLog.TANKNO с максимальным временем LOGTIME для каждого из TANKNO:
WELLID, TANKNO, TANKGEOMETRY
1, 1, 1 ->
1, 2, 2 ->
2, 1, 2
WELLID, LOGTIME,  TANKNO, TANKACTIVE
1, 13:00, 1, 1
1, 14:00, 1, 0 ->
1, 14:00, 2, 1
1, 15:00, 2, 1 ->
TANKNO, TANKGEOMETRY, TANKACTIVE
1       1         0
2       2         1

2ЮЮ:
Если честно, пока не понял что есть logGrouped и Suspend, но учту. Спасибо. Сделать две выборки и пробежаться программно я в состоянии сам, но не уверен, что это будет эффективнее, чем запрос.


ЮЮ   (2005-02-11 11:01:00) [5]

>если быстро не получится, то пробежаться по запросу

SELECT
 tanks.tankno, tankslogg.logtime, tankslogg.<прочие поля>
FROM
  tanks
  LEFT JOIN tankslog
  ON (tanks.tankno = logGrouped.tankno)
ORDER BY 1, 2 DESC

Осталось пробежаться по запросу и делать Suspend в случае смены первого поля и бежать дальше в противном случае.


Johnmen   (2005-02-11 10:40:00) [6]

>REA

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


REA   (2005-02-11 10:35:00) [7]

Автор хочет, чтобы было быстрее: можно select, join или если быстро не получится, то пробежаться по запросу. Пока сделал select (который на самом деле тоже план JOIN) [22] - вроде работает. С join пробовал тоже, но не хватает моих познаний - вариант как в [25] мне самому пожалуй не соорудить.
Спасибо за помощь.


Johnmen   (2005-02-11 09:41:00) [8]

>ЮЮ ©   (11.02.05 03:41) [25]

То, что ты написал, не есть "механизм подзапросов". Это просто соединение запроса с таблицей.
А то, что хочет автор, уже написали ранее...
И для каждой записи делать подзапрос ненапряжно, если есть соотв.индексы, и быстрее, чем на клиенте разбирать, и не факт, что медленнее, чем процедура, где наверняка будет запрос с агрегированием и группировкой. А группировка достаточно небыстрый процесс...


ЮЮ   (2005-02-11 03:41:00) [9]

>>ЮЮ ©   (10.02.05 12:03) [10]
>>Т.к. в IB нет механизма подзапросов,

>Johnmen ©   (10.02.05 12:30) [16]
>Хм... Что имеется в виду ?

Имеется в ввмду, что надо сделать соединение первой таблицы, результата агрегирующего запроса по второй и, наконец, самой второй таблицы. В MS SQL это выгдядедо бы так:

 SELECT tanks.tankno, tankslogg.*
 FROM
   tanks
   LEFT JOIN (
     SELECT tankno, MAX(logtime) maxlogtime
     FROM tankslog
     GROUP BY tankno
   ) logGrouped ON (tanks.tankno = logGrouped.tankno)
   LEFT JOIN tankslog ON
     (logGrouped.tankno = tankslog.tankno) AND
     (logGrouped.maxlogtime= tankslog.logtime)


А использовать SELECT в WHERE млм в качестве поля возвращаемого НД, ИМНО, не есть хороший стиль. Лучше уж на клиенте (или в ХП) провежаться один раз по двум курсорам и получить необходимые данные, чем для каждой записи выполнять отдельный подзапрос


REA   (2005-02-10 17:04:00) [10]

В [1] не работает, как я уже говорил. [19] отлично работает, но мне нужно дополнительное условие (wellid = 1 в обоих таблицах) и нужно несколько полей из таблицы 1 (см. [7]). Согласен, что у меня от недостатка опыта получается бред.

>Учитесь анализировать и понимать, что вам говорят !
Пока ничего особо не говорят, а только приводят примеры, которые не всегда работают. Спасибо за содействие и понимание.


Johnmen   (2005-02-10 14:28:00) [11]

Ну боже ты мой.........
Уже всё сказали про запрос в [1] и [19].
И даже его написали... Так нет же, придумаем свой бред...:)

Учитесь анализировать и понимать, что вам говорят !


REA   (2005-02-10 14:03:00) [12]

Спасибо. Про алиасы верю и уже переделал с алиасами.
На основе этого запроса получилось:

select T1.logtime, T1.tankactive, tt.tankgeometry from tankslog T1, tanks tt where (T1.wellid = 1) And (Tt.wellid = 1) And (tt.tankno = T1.tankno) And (T1.logtime = (select max(T2.logTime)
from Tankslog T2 where (T2.wellid = 1) And (T2.tankno = T1.tankno)))

Indexed Reads: 4 и 30. Это лучше чем 2 и 60?


Anatoly Podgoretsky   (2005-02-10 13:42:00) [13]

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


Johnmen   (2005-02-10 13:41:00) [14]

>Anatoly Podgoretsky ©   (10.02.05 13:38) [18]

Ну, само-собой...:)


Johnmen   (2005-02-10 13:39:00) [15]

Ты думаешь, что про алиасы я просто воздух сотрясал ? (в смысле, в форуме флудил :))

select * from tankslog T1
where T1.logtime = (select max(T2.logTime)
                   from Tankslog T2
                   where (T2.tankno = T1.tankno)))


Anatoly Podgoretsky   (2005-02-10 13:38:00) [16]

Johnmen ©   (10.02.05 12:03) [11]
Правильнее сказать префиксы, а псевдоними или явные названия таблиц без разницы, если конечно имена таблиц простые, английскии и нет вложенных запросов из самого себя.


REA   (2005-02-10 12:58:00) [17]

В таком виде (по мотивам 1) возвращает не то:
select tankno, logtime, tankactive from tankslog where
(logtime = (select max(tt.logTime) from Tankslog tt where (tt.tankno = tankslog.tankno)))

работает по мотивам 2 (wellid - часть primary ключа в обоих таблицах):

select tanks.tankno, tankslog.logtime
from tanks, tankslog
where (tanks.wellid=1) And (tankslog.wellid=1) And (tanks.tankno=tankslog.tankno) and
tankslog.logtime = (select max(tt.logtime) from tankslog tt where tt.wellid = 1 and TT.tankno = tanks.tankno)

но имхо многовато Indexed Reads: 2 и 60 на таблицах из 2 и 5 записей


Johnmen   (2005-02-10 12:30:00) [18]

>ЮЮ ©   (10.02.05 12:03) [10]
>Т.к. в IB нет механизма подзапросов,

Хм... Что имеется в виду ?

>REA   (10.02.05 12:22) [14]

Этот запрос в корне неверен.
Верный - в [1].


Sergey13   (2005-02-10 12:29:00) [19]

2[14] REA   (10.02.05 12:22)
>И в таком виде как ни странно работает:
Осталось выяснить правильно ли. 8-)


REA   (2005-02-10 12:22:00) [20]

И в таком виде как ни странно работает:

select tanks.tankno, tanks.tankgeometry, logtime, tankslog.tankactive from tanks, tankslog where
logtime = (select max(logTime) from Tankslog)

Планы:
PLAN (TANKSLOG NATURAL)
PLAN JOIN (TANKS NATURAL,TANKSLOG NATURAL)

Так как лучше то?


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо