powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / ADO.NET, LINQ, Entity Framework, NHibernate, DAL, ORM [игнор отключен] [закрыт для гостей] / Сложный LINQ запрос
25 сообщений из 35, страница 1 из 2
Сложный LINQ запрос
    #37221398
renaton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Доброго дня!
Имеются такие классы:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
//Класс для хранения настроек
public class OPData
    {
        public int ID
        {
            get;
            set;
        }
        public string TAG
        {
            get;
            set;
        }
        public string Name
        {
            get;
            set;
        }
        [DefaultValue(null)]
        public Nullable<double> MIN_VALUE
        {
            get;
            set;
        }
        [DefaultValue(null)]
        public Nullable<double> MAX_VALUE
        {
            get;
            set;
        }     
    }
//Класс для хранения значений
public class OPRecieveData
    {
        public string OPTag
        {
            get;
            set;
        }
        public DateTime OPDateTime
        {
            get;
            set;
        }
        public double Value
        {
            get;
            set;
        }
    }
Используя класс OPRecieveData так:
Код: plaintext
IList<OPRecieveData> Values = new IList<OPRecieveData>();
и в нем будут хранится секундные значения вида:
OPTagOPDateTimeValuetag118.04.2011 08:00:00.000250tag218.04.2011 08:00:00.0001000tag318.04.2011 08:00:00.00010tag118.04.2011 08:00:01.000260tag218.04.2011 08:00:01.0001050tag318.04.2011 08:00:01.00011tag118.04.2011 08:00:02.000255tag218.04.2011 08:00:02.0001080tag318.04.2011 08:00:02.0009.........tag118.04.2011 08:03:00.000240tag218.04.2011 08:03:00.0001010tag318.04.2011 08:03:00.00012tag118.04.2011 08:03:01.000245tag218.04.2011 08:03:01.0001050tag318.04.2011 08:03:01.00013tag118.04.2011 08:03:02.000270tag218.04.2011 08:03:02.0001070tag318.04.2011 08:03:02.00014.........
Используя класс OPData так:
Код: plaintext
IList<OPData> Params = new IList<OPData>();
и в нем будут хранится описание каждого параметр в виде:
IDTAGNameMIN_VALUEMAX_VALUE101tag1Parameter1200300102tag2Parameter29001100103tag3Parameter3nullnull
то есть MIN_VALUE и MAX_VALUE могут быть null, т.е. не задан интервал.
Вопрос: Используя LINQ необходимо получить на выходе усредненное 3-х минутное значение то есть брать интервал в 3 минуты с 00:00 до 00:03, 00:06 и т.д. и среднее находить так если указаны MIN_VALUE и MAX_VALUE - брать только те значения которые в заданном интервале, если не заданы, то брать все значения. То есть надо в результате получить что-то в виде:
IDTAGNameDateTimeValue101tag1Parameter118.04.2011 08:00:00.000255102tag2Parameter218.04.2011 08:00:00.0001043.33103tag3Parameter318.04.2011 08:00:00.00010101tag1Parameter118.04.2011 08:03:00.000251.66102tag2Parameter218.04.2011 08:03:00.0001043.33103tag3Parameter318.04.2011 08:03:00.00013...............
Как это можно записать на LINQ? Спасибо.
...
Рейтинг: 0 / 0
Сложный LINQ запрос
    #37221542
wcf.net.ru
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
            List<OPRecieveData> values = new List<OPRecieveData>
            { 
                new OPRecieveData { OPTag = "tag1", OPDateTime = DateTime.Parse("18.04.2011 08:00:00.000"), Value = 250 },
                new OPRecieveData { OPTag = "tag2", OPDateTime = DateTime.Parse("18.04.2011 08:00:00.000"), Value = 1000 },
                new OPRecieveData { OPTag = "tag3", OPDateTime = DateTime.Parse("18.04.2011 08:00:00.000"), Value = 10 },
                new OPRecieveData { OPTag = "tag1", OPDateTime = DateTime.Parse("18.04.2011 08:00:01.000"), Value = 260 },
                new OPRecieveData { OPTag = "tag2", OPDateTime = DateTime.Parse("18.04.2011 08:00:01.000"), Value = 1050 },
                new OPRecieveData { OPTag = "tag3", OPDateTime = DateTime.Parse("18.04.2011 08:00:01.000"), Value = 11 },
                new OPRecieveData { OPTag = "tag1", OPDateTime = DateTime.Parse("18.04.2011 08:00:02.000"), Value = 255 },
                new OPRecieveData { OPTag = "tag2", OPDateTime = DateTime.Parse("18.04.2011 08:00:02.000"), Value = 1080 },
                new OPRecieveData { OPTag = "tag3", OPDateTime = DateTime.Parse("18.04.2011 08:00:02.000"), Value = 9 },

                new OPRecieveData { OPTag = "tag1", OPDateTime = DateTime.Parse("18.04.2011 08:03:00.000"), Value = 240 },
                new OPRecieveData { OPTag = "tag2", OPDateTime = DateTime.Parse("18.04.2011 08:03:00.000"), Value = 1010 },
                new OPRecieveData { OPTag = "tag3", OPDateTime = DateTime.Parse("18.04.2011 08:03:00.000"), Value = 12 },
                new OPRecieveData { OPTag = "tag1", OPDateTime = DateTime.Parse("18.04.2011 08:03:01.000"), Value = 245 },
                new OPRecieveData { OPTag = "tag2", OPDateTime = DateTime.Parse("18.04.2011 08:03:01.000"), Value = 1050 },
                new OPRecieveData { OPTag = "tag3", OPDateTime = DateTime.Parse("18.04.2011 08:03:01.000"), Value = 13 },
                new OPRecieveData { OPTag = "tag1", OPDateTime = DateTime.Parse("18.04.2011 08:03:02.000"), Value = 270 },
                new OPRecieveData { OPTag = "tag2", OPDateTime = DateTime.Parse("18.04.2011 08:03:02.000"), Value = 1070 },
                new OPRecieveData { OPTag = "tag3", OPDateTime = DateTime.Parse("18.04.2011 08:03:02.000"), Value = 14 },
            };

            List<OPData> par = new List<OPData>
            {
                new OPData { ID = 101, TAG="tag1", Name="Parameter1", MIN_VALUE=200, MAX_VALUE=300 },
                new OPData { ID = 102, TAG="tag2", Name="Parameter2", MIN_VALUE=900, MAX_VALUE=1100 },
                new OPData { ID = 103, TAG="tag3", Name="Parameter3", MIN_VALUE=null, MAX_VALUE=null },
            };

            var query = values
                // объединяем по тегу
                .Join(par, v => v.OPTag, v => v.TAG, (d, p) => new { Data = d, Par = p })
                // применяем фильтр
                .Where(x => (x.Par.MIN_VALUE == null || x.Data.Value >= x.Par.MIN_VALUE)
                    && (x.Par.MAX_VALUE == null || x.Data.Value <= x.Par.MAX_VALUE))
                // группируем данные
                .GroupBy(x => new { x.Par, Date = x.Data.OPDateTime.AddMinutes(-x.Data.OPDateTime.Minute % 3).AddSeconds(-x.Data.OPDateTime.Second) })
                // выбираем данные
                .Select(g => new
                {
                    ID = g.Key.Par.ID,
                    TAG = g.Key.Par.TAG,
                    Name = g.Key.Par.Name,
                    DateTime = g.Key.Date,
                    Value = g.Average(t => t.Data.Value)
                });

            foreach (var x in query)
            {
                Console.WriteLine("{0}, {1}, {2}, {3}, {4}", x.ID, x.TAG, x.Name, x.DateTime, x.Value);
            }
...
Рейтинг: 0 / 0
Сложный LINQ запрос
    #37222039
stimpi
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
wcf.net.ru
у вас left join, а надо left outer join, если не будет записи в таблице ограничений, то для такого тега не будет результата у вас

немного другой подход
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
var range = new List<OPData>();
            var data = new List<OPRecieveData>();

            range.Add(new OPData() { TAG = "tag1", MIN_VALUE = 2, MAX_VALUE = 3 });
            range.Add(new OPData() { TAG = "tag2", MIN_VALUE = 2, MAX_VALUE = null });

            data.Add(new OPRecieveData() { OPTag = "tag1", OPDateTime = DateTime.Today.AddMinutes(0), Value = 1 });
            data.Add(new OPRecieveData() { OPTag = "tag1", OPDateTime = DateTime.Today.AddMinutes(2).AddDays(1), Value = 4 });
            data.Add(new OPRecieveData() { OPTag = "tag1", OPDateTime = DateTime.Today.AddMinutes(3).AddDays(1), Value = 1 });
            data.Add(new OPRecieveData() { OPTag = "tag1", OPDateTime = DateTime.Today.AddMinutes(4), Value = 2 });
            data.Add(new OPRecieveData() { OPTag = "tag2", OPDateTime = DateTime.Today.AddMinutes(1).AddDays(1), Value = 3 });
            data.Add(new OPRecieveData() { OPTag = "tag2", OPDateTime = DateTime.Today.AddMinutes(0), Value = 1 });
            data.Add(new OPRecieveData() { OPTag = "tag2", OPDateTime = DateTime.Today.AddMinutes(3).AddDays(1), Value = 1 });
            data.Add(new OPRecieveData() { OPTag = "tag2", OPDateTime = DateTime.Today.AddMinutes(5), Value = 5 });
            data.Add(new OPRecieveData() { OPTag = "tag2", OPDateTime = DateTime.Today.AddMinutes(1).AddDays(1), Value = 5 });

            var q = from d in data
                    join r in range on d.OPTag equals r.TAG into outer
                    from r in outer.DefaultIfEmpty(new OPData())
                    where d.Value >= (r.MIN_VALUE.HasValue ? r.MIN_VALUE : d.Value) &&
                        d.Value <= (r.MAX_VALUE.HasValue ? r.MAX_VALUE : d.Value)
                    select new
                    {
                        Tag = d.OPTag,
                        DateTimeNum = (int)new TimeSpan(d.OPDateTime.Ticks).TotalMinutes / 3,
                        Value = d.Value
                    } into i
                    group i by new { i.Tag, i.DateTimeNum } into g
                    select new
                    {
                        Tag = g.Key.Tag,
                        Date = new DateTime(TimeSpan.FromMinutes(g.Key.DateTimeNum * 3).Ticks),
                        Avg = g.Average(t => t.Value)
                    } into i
                    orderby i.Date
                    select i;

            foreach (var item in q)
                Console.WriteLine("{0} {1} {2}", item.Tag, item.Date, item.Avg);
...
Рейтинг: 0 / 0
Сложный LINQ запрос
    #37222129
wcf.net.ru
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
stimpiу вас left join, а надо left outer join, если не будет записи в таблице ограничений, то для такого тега не будет результата у вас

Да, не будет. Потому что у меня inner join, как ТС и просил - посмотрите внимательно на пример данных, которые надо в результате получить.

PS: А разница между left join и left outer join только в наличии опционального слова "outer"
...
Рейтинг: 0 / 0
Сложный LINQ запрос
    #37222812
renaton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Тут еще один нюанс, я конечное дико извиняюсь, но я не правильно интервалы 3-х минуток указал.
Вот так должно быть правильно: данные что лежат в интервале с 07:57:00.000 до 08:00:00.000 - среднее со временем 08:00:00.000, с 08:00:00.000 до 08:03:00.000 - среднее со временем 08:03:00.000, с 08:03:00.000 до 08:06:00.000 - среднее со временем 08:06:00.000, ...., с 08:57:00.000 до 09:00:00.000 - среднее со временем 09:00:00.000 .
Спасибо.
...
Рейтинг: 0 / 0
Сложный LINQ запрос
    #37223047
Фотография Верблюд
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
renatonCпасибо. При выводе результата вычти 3 минуты
...
Рейтинг: 0 / 0
Сложный LINQ запрос
    #37223370
stimpi
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
wcf.net.ruДа, не будет. Потому что у меня inner join, как ТС и просил - посмотрите внимательно на пример данных, которые надо в результате получить.

читаем внимательно
renaton брать только те значения которые в заданном интервале, если не заданы, то брать все значения

wcf.net.ruPS: А разница между left join и left outer join только в наличии опционального слова "outer"


разница между "правпильно" и "неправильно" , всего лишь в суффиксе НЕ )
...
Рейтинг: 0 / 0
Сложный LINQ запрос
    #37223380
Фотография Верблюд
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
stimpiчитаем внимательно
renatonбрать только те значения которые в заданном интервале, если не заданы, то брать все значения

читаем еще внимательней

renatonТо есть надо в результате получить что-то в виде:
IDTAGNameDateTimeValue101tag1Parameter118.04.2011 08:00:00.000255102tag2Parameter218.04.2011 08:00:00.0001043.33103tag3Parameter318.04.2011 08:00:00.00010101tag1Parameter118.04.2011 08:03:00.000251.66102tag2Parameter218.04.2011 08:03:00.0001043.33103tag3Parameter318.04.2011 08:03:00.00013

где тут хотя бы один пример без ID/Name ???
...
Рейтинг: 0 / 0
Сложный LINQ запрос
    #37223390
stimpi
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Верблюд,

Троеточие где съели ? )

Читаем более чем еще внимательней выделенное мною жириным.
...
Рейтинг: 0 / 0
Сложный LINQ запрос
    #37223393
Фотография Верблюд
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
stimpiВерблюд,

Троеточие где съели ? )

Читаем более чем еще внимательней выделенное мною жириным.

Я лично общался с ТС по email и лучше тебя знаю в чем суть вопроса
...
Рейтинг: 0 / 0
Сложный LINQ запрос
    #37223394
stimpi
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Где сказано, что не надо выводить усредненое, если нет интервала по тегу в таблице интервалов ?
...
Рейтинг: 0 / 0
Сложный LINQ запрос
    #37223397
Фотография Верблюд
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
stimpiwcf.net.ruPS: А разница между left join и left outer join только в наличии опционального слова "outer"


разница между "правпильно" и "неправильно" , всего лишь в суффиксе НЕ )

1. между "правпильно" и "неправильно" разница больше чем в суффиксе "не" - там еще буква "п" затесалась.
2. между left join и left outer join разница только в написании - по смыслу это одно и тоже действие с точностью 100%.
...
Рейтинг: 0 / 0
Сложный LINQ запрос
    #37223398
stimpi
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ВерблюдstimpiВерблюд,

Троеточие где съели ? )

Читаем более чем еще внимательней выделенное мною жириным.

Я лично общался с ТС по email и лучше тебя знаю в чем суть вопроса

вот так баги, "ака фичи" появляются
...
Рейтинг: 0 / 0
Сложный LINQ запрос
    #37223399
stimpi
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
держи
ВерблюдrenatonCпасибо. При выводе результата вычти 3 минуты
не правильно, надо добавлять на выходе, а не вычитать
...
Рейтинг: 0 / 0
Сложный LINQ запрос
    #37223400
Фотография Верблюд
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
stimpiВерблюдпропущено...


Я лично общался с ТС по email и лучше тебя знаю в чем суть вопроса

вот так баги, "ака фичи" появляются

Еще раз. Это не баги и не фичи. Это просто факт, что для каждого tagN существует запись в таблице.

ЗЫЖ Многоточие кстати, на null очень сильно не похоже. Это так навсякий
...
Рейтинг: 0 / 0
Сложный LINQ запрос
    #37223401
Фотография Верблюд
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
stimpiдержи
Верблюдпропущено...
При выводе результата вычти 3 минуты
не правильно, надо добавлять на выходе, а не вычитать

Не суть важно.
...
Рейтинг: 0 / 0
Сложный LINQ запрос
    #37223402
stimpi
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ВерблюдЕще раз. Это не баги и не фичи. Это просто факт, что для каждого tagN существует запись в таблице.

ЗЫЖ Многоточие кстати, на null очень сильно не похоже. Это так навсякий

ага и фраза
renatonТо есть надо в результате получить что-то в виде:

что-то не сильно на последнюю интстанцию о правильности говорит.
...
Рейтинг: 0 / 0
Сложный LINQ запрос
    #37223404
stimpi
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Верблюдstimpiдержи
пропущено...

не правильно, надо добавлять на выходе, а не вычитать

Не суть важно.

спасибо, посмеялся )
...
Рейтинг: 0 / 0
Сложный LINQ запрос
    #37223410
Фотография Верблюд
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
stimpiчто-то не сильно на последнюю интстанцию о правильности говорит.

Я думаю что Ренат сам дальше с запросом разберется, если что вдруг не так. В любом случае его не конкретное решение интересовало, а то, как это должно выглядеть будучи написаным на LINQ. Если внимательно посмотреть, то там все расписано и по полочкам разложено даже с коментариями, что бы потом можно было под реальную задачу адаптировать.
...
Рейтинг: 0 / 0
Сложный LINQ запрос
    #37223805
renaton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не могу сделать группировку :( Помогите пожалуйста...
...
Рейтинг: 0 / 0
Сложный LINQ запрос
    #37223815
renaton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вот здесь:
Код: plaintext
.GroupBy(x => x.Data.OPCHDADateTime.AddMinutes(-x.Data.OPCHDADateTime.Minute % 3).AddSeconds(-x.Data.OPCHDADateTime.Second))
не совсем понимаю что надо изменить? И минусы здесь на что влияют?
...
Рейтинг: 0 / 0
Сложный LINQ запрос
    #37224153
stimpi
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
renatonВот здесь:
Код: plaintext
.GroupBy(x => x.Data.OPCHDADateTime.AddMinutes(-x.Data.OPCHDADateTime.Minute % 3).AddSeconds(-x.Data.OPCHDADateTime.Second))
не совсем понимаю что надо изменить? И минусы здесь на что влияют?

омфг, что тут еще-то объяснять, даты приводятся к вашим диапазонам, отнимаются минуты и секунды у всех дат чтоб они подходили к вашим отметкам с интервалом в 3, только опять же бага тут если у времени будут милисекунды, они тут не вычитываются
...
Рейтинг: 0 / 0
Сложный LINQ запрос
    #37224158
stimpi
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
осмотрите мой вариант, может понятней будет, там другой подход к группировке
...
Рейтинг: 0 / 0
Сложный LINQ запрос
    #37224194
renaton
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
stimpiомфг, что тут еще-то объяснять, даты приводятся к вашим диапазонам, отнимаются минуты и секунды у всех дат чтоб они подходили к вашим отметкам с интервалом в 3, только опять же бага тут если у времени будут милисекунды, они тут не вычитываются
хмм.... у меня данные могуть быть и с ненулевым значением миллисекунды, т.е. может быть 20.04.2011 12:00:00.015. Надо и такие данные тоже учитывать в выборке. Спасибо.
...
Рейтинг: 0 / 0
Сложный LINQ запрос
    #37224198
stimpi
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
так почему не можете сделать группировку ? что за ошибка ?
...
Рейтинг: 0 / 0
25 сообщений из 35, страница 1 из 2
Форумы / ADO.NET, LINQ, Entity Framework, NHibernate, DAL, ORM [игнор отключен] [закрыт для гостей] / Сложный LINQ запрос
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]