Гость
Форумы / ADO.NET, LINQ, Entity Framework, NHibernate, DAL, ORM [игнор отключен] [закрыт для гостей] / Сложный LINQ запрос / 25 сообщений из 35, страница 1 из 2
18.04.2011, 12:44
    #37221398
renaton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сложный LINQ запрос
Доброго дня!
Имеются такие классы:
Код: 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
18.04.2011, 21:43
    #37221542
wcf.net.ru
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сложный LINQ запрос
Код: 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
19.04.2011, 10:53
    #37222039
stimpi
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сложный LINQ запрос
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
19.04.2011, 11:27
    #37222129
wcf.net.ru
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сложный LINQ запрос
stimpiу вас left join, а надо left outer join, если не будет записи в таблице ограничений, то для такого тега не будет результата у вас

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

PS: А разница между left join и left outer join только в наличии опционального слова "outer"
...
Рейтинг: 0 / 0
19.04.2011, 14:56
    #37222812
renaton
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сложный LINQ запрос
Тут еще один нюанс, я конечное дико извиняюсь, но я не правильно интервалы 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
19.04.2011, 16:22
    #37223047
Верблюд
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сложный LINQ запрос
renatonCпасибо. При выводе результата вычти 3 минуты
...
Рейтинг: 0 / 0
19.04.2011, 18:52
    #37223370
stimpi
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сложный LINQ запрос
wcf.net.ruДа, не будет. Потому что у меня inner join, как ТС и просил - посмотрите внимательно на пример данных, которые надо в результате получить.

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

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


разница между "правпильно" и "неправильно" , всего лишь в суффиксе НЕ )
...
Рейтинг: 0 / 0
19.04.2011, 19:02
    #37223380
Верблюд
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сложный LINQ запрос
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
19.04.2011, 19:08
    #37223390
stimpi
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сложный LINQ запрос
Верблюд,

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

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

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

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

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


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

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

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

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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


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