Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2008.07.20;
Скачать: CL | DM;

Вниз

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

 
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;
Скачать: CL | DM;

Наверх




Память: 0.57 MB
Время: 0.026 c
2-1213337899
kivadim
2008-06-13 10:18
2008.07.20
как получить значение свойства класса из внешней программы?


2-1213984177
Res
2008-06-20 21:49
2008.07.20
exit и procedure


15-1212655691
Alkid
2008-06-05 12:48
2008.07.20
Planner


2-1213699641
Alex_C
2008-06-17 14:47
2008.07.20
Маштабирование окна


11-1191960858
ElectriC
2007-10-10 00:14
2008.07.20
Проблема с KeyPreview