Предварительный запрос с linq2sql для данных с пробелами - PullRequest
0 голосов
/ 11 апреля 2011

Привет, у меня есть таблица: значения с ValueId, Timestamp, Value и BelongTo.Каждые 15 минут в эту таблицу вставляется новая строка с новым значением, текущей отметкой времени и конкретным полем BelongTo.И теперь я хочу найти пропуски, я имею в виду значения, в которых метки времени друг за другом превышают 15 минут.

Я пытался это сделать:

var gaps = from p1 in db.T_Values
                       join p2 in db.T_Values on p1.TimeStamp.AddMinutes(15) equals p2.TimeStamp
                       into grups where !grups.Any() select new {p1};

, и это работает, но я не знаюесли это optimall, что вы думаете?и я не знаю, как я могу добавить, где p1.BelongTo == 1. Потому что этот запрос ищет все данные.

Джон сказал

var gaps = from p1 in db.T_Values
           where p1.BelongTo == 1
           where !db.T_Values.Any(p2 => p1.TimeStamp.AddMinutes(15) == p2.Timestamp)
           select p1;

Джон этот последний запрос переведен на:

exec sp_executesql N'SELECT [t0].[ValueID], [t0].[TimeStamp], [t0].[Value],
                    [t0].[BelongTo], [t0].[Type]
FROM [dbo].[T_Values] AS [t0]
WHERE (NOT (EXISTS(
SELECT NULL AS [EMPTY]
FROM [dbo].[T_Values] AS [t1]
WHERE DATEADD(ms, (CONVERT(BigInt,@p0 * 60000)) % 86400000,
DATEADD(day, (CONVERT(BigInt,@p0 * 60000)) / 86400000, [t0].[TimeStamp])) = [t1].[TimeStamp]
))) AND ([t0].[BelongTo] = @p1)',N'@p0 float,@p1 int',@p0=15,@p1=1

, и это работает, если все строки не имеют одинаковое принадлежность, когда есть строки с BelongTo со многими различными значениями, тогда я заметил, что мне нужно добавить в sql: и [t1] .BelongTo =1, который в конечном итоге должен выглядеть следующим образом:

N'SELECT [t0].[ValueID], [t0].[TimeStamp], [t0].[Value], [t0].[BelongTo], [t0].[Type]
FROM [dbo].[T_Values] AS [t0]
   WHERE (NOT (EXISTS(
SELECT NULL AS [EMPTY]
FROM [dbo].[T_Values] AS [t1]
WHERE DATEADD(ms, (CONVERT(BigInt,@p0 * 60000)) % 86400000, 
DATEADD(day, (CONVERT(BigInt,@p0 * 60000)) / 86400000, [t0].[TimeStamp])) = [t1].[TimeStamp]
and [t1].BelongTo = 1  
  ))) AND ([t0].[BelongTo] = @p1)',N'@p0 float,@p1 int',@p0=15,@p1=1

другими словами:

SELECT  TimeStamp
FROM [dbo].[T_Values] AS [t0]
WHERE NOT( (EXISTS (SELECT NULL AS [EMPTY]
FROM [dbo].[T_Values] AS [t1]
WHERE DATEADD(MINUTE, 15, [t0].[TimeStamp]) = [t1].[TimeStamp])))
AND ([t0].[BelongTo] = 1)

может измениться на

SELECT  TimeStamp
FROM [dbo].[T_Values] AS [t0]
WHERE NOT( (EXISTS (SELECT NULL AS [EMPTY]
FROM [dbo].[T_Values] AS [t1]
WHERE DATEADD(MINUTE, 15, [t0].[TimeStamp]) = [t1].[TimeStamp] and [t1].BelongTo=1)))
AND ([t0].[BelongTo] = 1)

, но я все еще думаю, как я могу добавить эток ссылкеq

Ответы [ 2 ]

1 голос
/ 11 апреля 2011

Ну, добавить дополнительное условие where легко (и я удалю бессмысленный анонимный тип в то же время):

var gaps = from p1 in db.T_Values
           where p1.BelongTo == 1
           join p2 in db.T_Values
           on p1.TimeStamp.AddMinutes(15) equals p2.TimeStamp
           into grups
           where !grups.Any()
           select p1;

Я не уверен, почему вы группируете... Я бы подумал, что это будет проще:

var gaps = from p1 in db.T_Values
           where p1.BelongTo == 1
           where !db.T_Values.Any(p2 => p1.TimeStamp.AddMinutes(15) == p2.Timestamp)
           select p1;

Что касается производительности - посмотрите на сгенерированный SQL и как он выглядит в профилировщике SQL.

РЕДАКТИРОВАТЬ: Если вам нужно BelongTo проверка в обеих версиях (имеет смысл), я бы предложил это:

var sequence = db.T_Values.Where(p => p.BelongTo == 1);

var gaps = from p1 in sequence
           where !sequence.Any(p2 => p1.TimeStamp.AddMinutes(15) == p2.Timestamp)
           select p1;
0 голосов
/ 11 апреля 2011

Как насчет

var gaps = dbT_Values.Take(dbT_Values.Count()-1)
                     .Select((p, index) => new {P1 = p, P2 = dbT_Values.ElementAt(index + 1)})
                     .Where(p => p.P1.BelongsTo == 1 && p.P1.TimeStamp.AddMinutes(15).Equals(p.P2.TimeStamp)).Select(p => p.P1);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...