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

Вниз

Хранимая процедура   Найти похожие ветки 

 
Knight ©   (2008-06-17 09:01) [0]

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

В результирующий набор данных должны попасть строки из табл1 для которых табл1.поле1=табл2.поле1 AND табл2.поле2=0 ... или табл1.поле1 попадает в интервал значений табл2.поле1 такой, что хотя бы один из них имеет табл2.поле2=0

табл1
---------------------
   поле1     поле2
---------------------
1  |  1   | значение1
2  |  4   | значение2
3  |  6   | значение3
4  |  7   | значение4
5  |  14  | значение5

табл2
---------------------
   поле1     поле2
---------------------
1  |  2   | 23
2  |  5   | 0
3  |  7   | 0
4  |  9   | 2322
5  |  11  | 111
6  |  13  | 232
7  |  15  | 0


 
Knight ©   (2008-06-17 09:04) [1]

результат
---------------------
  поле1     поле2
---------------------
1  |  4   | значение2
2  |  6   | значение3
3  |  7   | значение4
4  |  14  | значение5


 
Knight ©   (2008-06-17 09:06) [2]

Расширю табл1, чтобы выкинуло по-больше.

табл1
---------------------
  поле1     поле2
---------------------
1  |  1   | значение1
2  |  4   | значение2
3  |  6   | значение3
4  |  7   | значение4
5  |  10  | значение5
6  |  12  | значение6
7  |  14  | значение7

результат
---------------------
 поле1     поле2
---------------------
1  |  4   | значение2
2  |  6   | значение3
3  |  7   | значение4
4  |  14  | значение7


 
oldman ©   (2008-06-17 09:08) [3]


> Помогите осознать логику процедуры


Логика 1
1. Взять запись табл1, оценить ее поле1
2. Найти соответствующую запись в табл2, оценив табл2.поле1
3. проверить у нужной записи в табл2 поле2
4. если оно равно 0, запись из табл1 поместить в набор данных

Логика 2
1. Поставить фильтр табл2 такой, что табл2.поле2=0
2. Работая теперь с табл2.поле1 выбрать нужное из табл1

Логика 3
Если тебе нужен код sql-запроса, или код процедуры, так и скажи...
А то написал простейшее условие с "помогите понять логику"
:)))


 
Knight ©   (2008-06-17 09:19) [4]

Спасибо... код я сам напишу главное понять с какого боку подойти :)

Я так понял, что надо сделать выборку из табл2 во временую таблицу в которую войдут все строки из нужного интервала табл1.поле1
(например, для интревала 6-12 из табл1 выбрать 5-13 из табл2)

После пробегаться по выборке из табл1 и проверять ближайшие значения из временной таблицы. Напомните только как в sql найти ближайшее в меньшую сторону, а потом в большую сторону :)


 
Sergey13 ©   (2008-06-17 09:21) [5]

> [0] Knight ©   (17.06.08 09:01)

А насколько велика вторая таблица?


 
Knight ©   (2008-06-17 09:22) [6]

Они обе ОЧЕНЬ большие.


 
Sergey13 ©   (2008-06-17 09:22) [7]

+ к [5] Sergey13 ©   (17.06.08 09:21)

и постоянна.


 
Knight ©   (2008-06-17 09:24) [8]

В табл1 добавляется примерно 50 тысяч записей в день, во вторую 20 тысяч.


 
Knight ©   (2008-06-17 09:24) [9]

т.е. наоборот...


 
Knight ©   (2008-06-17 09:27) [10]

Раньше обходился простыми запросами.. процедурами не пользовался, а оказывается удобная штука :)


 
Knight ©   (2008-06-17 09:29) [11]

поле1 типа datetime в первую таблицу значения идут примерно раз в 5-6 секунд, во вторую каждые 2.


 
Sergey13 ©   (2008-06-17 09:30) [12]

> [8] Knight ©   (17.06.08 09:24)

Ну, тогда с "доработкой" второй таблицы до "удобного вида" наверное не покатит. 8-)

Тогда в лоб
1. Берем запись и Т1
2. если есть четкое соответствие в Т2 там проверяем поле2
3. если нет соответствия
3.1 берем максимальное, меньше данного, проверяем П2 у него
3.2 берем минимальное, больше данного, проверка П2
4. На основани пункта 3 принимаем решение


 
Knight ©   (2008-06-17 09:42) [13]

> [12] Sergey13 ©   (17.06.08 09:30)

т.е. для @TimeStart, @TimeEnd
1) Создаём временную таблицу результата
2) Делаем выборку из табл2 с мин>=@TimeStart и макс<=@TimeEND
3) Пробегаем по выборке из табл1 сверяя текущее @dt со поле2=0 для мин(поле1)>=@dt и макс(поле1)<=@dt

так?


 
Knight ©   (2008-06-17 09:44) [14]

Если нулевое найдено, то запись вставляется в таблицу результата... из которой в конце делает выборка всех строк.


 
Sergey13 ©   (2008-06-17 09:47) [15]

> [13] Knight ©   (17.06.08 09:42)

Я не очень знаю мелкомягкий синтаксис.
Для скольких записей из Т1 нужна выборка?


 
Knight ©   (2008-06-17 09:49) [16]

> [15] Sergey13 ©   (17.06.08 09:47)

Зависит от заданного интревала времени... мож за день, мож за неделю, а мож за год :)


 
Sergey13 ©   (2008-06-17 09:55) [17]

> [16] Knight ©   (17.06.08 09:49)

Тогда возможно нужна не процедура, а функция, которая возвращает да/нет для КАЖДОЙ записи Т1.


 
Knight ©   (2008-06-17 11:02) [18]

Мдя.. 11 секунд за день... а за неделю пока не дождался :)))


 
Knight ©   (2008-06-17 11:02) [19]

О! (00:02:23)


 
ЮЮ ©   (2008-06-17 11:14) [20]

>
> Зависит от заданного интревала времени&#133 мож за день, мож
> за неделю, а мож за год :)

Что-то полей datetime не наблюдаю


> Раньше обходился простыми запросами&#133 процедурами не пользовался,
> а оказывается удобная штука :)

Ешё есть UDF. Для сективных выборок ещё более удобны; можно использовать как таблицы в запросах :)

какая связь то? Доморщенная что ли? Типа 0(1)&#1330(1) ? Или всеже eсть мастер-таблица, где есть все значения
 1-2,  4-7, 9-15 поля1 ?


 
Knight ©   (2008-06-17 11:30) [21]

В UDF оформил проверку нуля

CREATE FUNCTION IsZero (
 @ObjID INT,
 @dt datetime
)
RETURNS tinyint AS
BEGIN
 if exists(SELECT 1 FROM T2
   WHERE ttime BETWEEN (Select MAX(ttime) FROM T2 WHERE ttime<=@dt AND ObjID=@ObjID)
     AND (Select MIN(ttime) FROM T2 WHERE ttime>=@dt AND ObjID=@ObjID)
     AND v2=0 AND ObjID=@ObjID)

   RETURN 1
 RETURN 0
END


 
ЮЮ ©   (2008-06-17 11:32) [22]

> или табл1.поле1 попадает в интервал значений табл2.поле1
> такой, что хотя бы один из них имеет табл2.поле2=0

т.е. если и есть запись для 15, не не 0
 15  | 222
выводим
 14  | значение5
?


 
Knight ©   (2008-06-17 11:36) [23]

> [22] ЮЮ ©   (17.06.08 11:32)

таб2   9   | 2322
-> таб1   7   | значение4
таб2   11  | 111
-> таб1   10  | значение5
таб2   13  | 232
-> таб1   12  | значение6
таб2   15  | 0


 
ЮЮ ©   (2008-06-17 11:37) [24]

> CREATE FUNCTION IsZero (
> @ObjID INT,
> @dt datetime
> )


Это тоже в точке времени, а не на интервале. Какая тогда разница, за день или за неделю?


 
Knight ©   (2008-06-17 11:43) [25]

> [24] ЮЮ ©   (17.06.08 11:37)

Эта точка времени для проверки из процедуры

CREATE PROCEDURE GetBlaBla(
 @ObjID INT,
 @TimeStart datetime,
 @TimeEnd datetime
)
AS
BEGIN
 /* Procedure body */
                   
 SELECT ttime, v1 INTO #Temp FROM T1 WHERE ttime BETWEEN @TimeStart AND @TimeEnd AND IsZero(@ObjID,ttime)=1
 
 SELECT * FROM #Temp
 
 Drop table #Temp
END


 
Knight ©   (2008-06-17 11:47) [26]

Всё ли так и можно ли это как-то ускорить?


 
ЮЮ ©   (2008-06-17 11:47) [27]

> что хотя бы один из них имеет табл2.поле2=0


а если оба 0

 5  | 0
 6  | 666
 7  | 0

 5  | значение5
 6  | значение6
 7  | значение7

что для 6 выводить значение5 или значение7

Да и в примере у тебя есть

2  |  5   | 0
3  |  7   | 0

3  |  6   | значение3

Почему у тебя она (6-ка) не попала в результат?


 
Knight ©   (2008-06-17 11:49) [28]

> [27] ЮЮ ©   (17.06.08 11:47)

Почему не попала?

результат
---------------------
 поле1     поле2
---------------------
1  |  4   | значение2
2  |  6   | значение3
3  |  7   | значение4
4  |  14  | значение5


 
Knight ©   (2008-06-17 11:54) [29]

> [27] ЮЮ ©   (17.06.08 11:47)

Есть табл1.поле1 и табл2.поле1 табл2.поле2

строка 1 значение - табл2.поле1
строка   значение - табл1.поле1
строка 2 значение - табл2.поле1

если табл2.поле2=0 в 1 или 2 то табл1.поле2 включается в таблицу результата.


 
ЮЮ ©   (2008-06-17 12:05) [30]

а если объект попадет в интервал несколько раз, коль ты ещё и интервал задействуещь? Или поле1 уникально в обеих таблицах?


 
Knight ©   (2008-06-17 12:20) [31]

> [30] ЮЮ ©   (17.06.08 12:05)

Поле1 datetime


 
ЮЮ ©   (2008-06-17 12:22) [32]

> Всё ли так и можно ли это как-то ускорить?

А индексы в таблицах есть?
Как долго работает запрос типа
 Select
   ObjID, MAX(ttime) MaxTime,  MIN(ttime) MinTime  
 FROM T2
 WHERE ttime BETWEEN @TimeStart AND @TimeEnd
 GROUP BY ObjID
за день, за неделю?


 
Knight ©   (2008-06-17 12:27) [33]

IsZero работает 282 ms.

GetBlaBla
за день   0.11 мин.
за 5 дней 2.3 мин


 
ЮЮ ©   (2008-06-17 12:38) [34]

> [31] Knight ©   (17.06.08 12:20)
> > [30] ЮЮ ©   (17.06.08 12:05)
>
> Поле1 datetime


По примеру и не догадаешься :)

Итак в определенные промежутки времкни еешьу записи пишутся
а) в table2 в формате
0 / не ноль

б) в table1 в формате
 какаое-то значение

в) в обе таблицы сразу.

Хочется
 &laquo;проредить&raquo; table1, оставив те записи, пока взведен флаг &laquo;в table2 все ещё стоит 0&raquo;

Тогда два цикла по двум курсорам. В во внешнем цикле по table1 &laquo;скользишь&raquo; по table2 до нужной записи в курсоре по table1 и взводишь/сбрасываешь флаг. В зависимости от его значения выводишь или нет записсь из table1 в результирующий НД.


> [29] Knight ©   (17.06.08 11:54)


> строка 1 значение &#151; табл2.поле1
> строка   значение &#151; табл1.поле1
> строка 2 значение &#151; табл2.поле1


Учитывая это можно и в одном цикле по одному курсору, в запросе которого объединить записи из обких таблиц


 
Knight ©   (2008-06-17 12:49) [35]

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


 
ЮЮ ©   (2008-06-17 12:59) [36]

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

А что ты хочешь показать? Почему показания только одного и только в те моменты, когда нет показаний другого?


 
Knight ©   (2008-06-17 13:03) [37]

> [36] ЮЮ ©   (17.06.08 12:59)

Когда показания второго нулевые, то показания первого точнее.


 
Knight ©   (2008-06-17 16:08) [38]

Переделал... вот так стало
за 1 день 0.3 мин
за 5 дней 1.6 мин.

Мож кто проверит не напартачил ли чего? %)

T1 - ttime, v1
T2 - ttime, v2

CREATE PROCEDURE GetBlaBla(
 @ObjID INT,
 @TimeStart datetime,
 @TimeEnd datetime
)
AS
BEGIN
 /* Procedure body */
                   
 DECLARE @Max datetime
 DECLARE @Min datetime
 
 SET @Max=(SELECT MIN(ttime) FROM T2 WHERE ttime>=@TimeEnd AND ObjID=@ObjID)
 SET @Min=(SELECT MAX(ttime) FROM T2 WHERE ttime<=@TimeStart AND ObjID=@ObjID)
 
 SELECT a.ttime, a.v1))
  FROM T1 a
     WHERE a.ttime BETWEEN @TimeStart AND @TimeEnd
       AND a.ObjID=@ObjID
       AND exists(SELECT 1 FROM T2
        WHERE ttime
             BETWEEN (Select MAX(ttime) FROM T2 WHERE ttime<=a.ttime AND ObjID=@ObjID)
        AND (Select MIN(ttime) FROM T2 WHERE ttime>=a.ttime AND ObjID=@ObjID)
           AND v2=0 AND ObjID=@ObjID AND ttime BETWEEN @Min AND @Max)
END


 
Knight ©   (2008-06-17 16:37) [39]

Напартачил... идёт просто выборка всех записей за период из Т1


 
ANB   (2008-06-17 22:28) [40]


> Они обе ОЧЕНЬ большие.

Скока миллионов записей ?



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

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

Наверх




Память: 0.55 MB
Время: 0.055 c
3-1202888260
patrick1968
2008-02-13 10:37
2008.07.20
BDE


2-1214074663
Igor23
2008-06-21 22:57
2008.07.20
Подскажите новечку плиз D7+MySQL


2-1213700808
Skary
2008-06-17 15:06
2008.07.20
TShellListView. Как мне узнать путь к каждому выделенному файлу


15-1212524487
alex-drob
2008-06-04 00:21
2008.07.20
Отличие packed record от record


1-1195553133
DVM
2007-11-20 13:05
2008.07.20
TWinControl.WMPaint от Delphi7 запостите пожалуйста.





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский