powered by simpleCommunicator - 2.0.51     © 2025 Programmizd 02
Форумы / ADO.NET, LINQ, Entity Framework, NHibernate, DAL, ORM [игнор отключен] [закрыт для гостей] / Выборка первой группы записей
25 сообщений из 25, страница 1 из 1
Выборка первой группы записей
    #37355857
AlexMAS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Здравствуйте.

Необходима помощь в написании красивого запроса :)

Допустим, у нас есть некая последовательность:

Код: plaintext
... 5, 5, 5, ..., 10, 10, 10, ..., 5, 5, 5, ..., 10, 10, 10, ..., 5, 5, 5, ...

которая представлена, например, в виде такой таблицы:

Код: 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.
declare @data table (Id int identity, Value int)

-- 1-я группа 5-ок
insert into @data (Value) values ( 5 )
insert into @data (Value) values ( 5 )
insert into @data (Value) values ( 5 )

-- 1-я группа 10-ок
insert into @data (Value) values ( 10 )
insert into @data (Value) values ( 10 )
insert into @data (Value) values ( 10 )

-- 2-я группа 5-ок
insert into @data (Value) values ( 5 )
insert into @data (Value) values ( 5 )
insert into @data (Value) values ( 5 )

-- 2-я группа 10-ок
insert into @data (Value) values ( 10 )
insert into @data (Value) values ( 10 )
insert into @data (Value) values ( 10 )

-- 3-я группа 5-ок
insert into @data (Value) values ( 5 )
insert into @data (Value) values ( 5 )
insert into @data (Value) values ( 5 )

Этой последовательностью может быть и последовательность сущностей, не имеет значения.

Из представленной коллекции нужно выбрать первую группу десяток. (Запрос должен импортироваться в Linq to Entity/NHibernate и представлять один единственный Select.)

Заранее спасибо за участие! :)
...
Рейтинг: 0 / 0
Выборка первой группы записей
    #37355888
няка
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
AlexMAS,

этот вопрос наверно лучше было бы задать в ветку по БД
и вопрос глупый, в реляционных БД не существует порядка следования записей
...
Рейтинг: 0 / 0
Выборка первой группы записей
    #37355903
AlexMAS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
няка,

Уважаемый, скорей ваш ответ глупый. Плиз, не засоряйте ветку.
...
Рейтинг: 0 / 0
Выборка первой группы записей
    #37355946
ViPRos
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AlexMAS,

тебе сказали что в субд нет порядка
нумеруй последовательности (номер, или таймстамп или еще что) и не обзывай адекватов
а то забаню нафиг!!!
...
Рейтинг: 0 / 0
Выборка первой группы записей
    #37355963
Фотография Konst_One
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
чисто теоретически , ТСу должны помочь оконные ф-ии, с которыми к сожалению в mssql не очень. посмотрите в форуме по Microsoft SQL Server, там были аналогичные вопросы по последовательностям (CTE, lead/lag)
...
Рейтинг: 0 / 0
Выборка первой группы записей
    #37355983
AlexMAS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ViPRos,

>> тебе сказали что в субд нет порядка
>> нумеруй последовательности (номер, или таймстамп или еще что)

Товарищ, чем вам "Id int identity" не нумерация последовательности? Считайте, что у каждого значения есть порядковый номер и/или дата создания записи. Или что по вашему "порядок в СУБД"?

>> и не обзывай адекватов
>> а то забаню нафиг!!!

Тяжелый понедельник?

>> этот вопрос наверно лучше было бы задать в ветку по БД

Не лучше, поскольку задача, скорей касается LINQ + ORM. Считайте, что каждая запись - это класс типа { Id, [Time, ] Value }.


P.s. Если дельного предложения нет или вы не можете дать ответ, то зачем писать "вопрос глупый". Я по вашему попросил помощи у здравомыслящей общественности просто так? Предварительно не взвесив все "за" и "против"? Охотно приму все ответы, включая те, которые укажут, что данная задача не имеет простого решения с обоснованием "почему".
...
Рейтинг: 0 / 0
Выборка первой группы записей
    #37355984
AlexMAS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Konst_One,

Спасибо
...
Рейтинг: 0 / 0
Выборка первой группы записей
    #37356032
няка
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
AlexMAS,

в условии нигде не было написано что айдишка это упорядочивающий элемент
видимо увидал слово глупый и кровавая пелена затмила разум
а в ветку по БД таки пошел
...
Рейтинг: 0 / 0
Выборка первой группы записей
    #37356047
ViPRos
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
няка,

на int id не обратил внимание
тогда можно выбрать

выбираем допустим все 10 - ки сортируем по ИД
анализируем не разрывает ли порядок в ИД запись с другим значением
точки разрыва = начало / конец группы
...
Рейтинг: 0 / 0
Выборка первой группы записей
    #37357255
stimpi
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
первая последовательность десяток сортироана по ID, если искать 2ую и в том же духе последовательности, то надо дополнительные
ROW_NUMBER крутить в подзапросы

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
select extd.*
from @data extd
  join  (select d.startId, d.endId, ROW_NUMBER() OVER (ORDER BY startid) row_num
      from (
      select d1.Id startId, d2.Id endId
      from @data d1
        left join @data d2 on d1.id < d2.id 
      where d1.Value =  10 
        and d2.Value <>  10 
        and not exists(select * from @data d3 where d3.Id > d1.Id and d3.Id < d2.Id and d3.Value <>  10 )) d
    ) dd on extd.Id >= dd.startId and extd.Id < dd.endId and dd.row_num =  1 
...
Рейтинг: 0 / 0
Выборка первой группы записей
    #37357260
stimpi
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
для NHibernate named queries
...
Рейтинг: 0 / 0
Выборка первой группы записей
    #37357606
няка
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
stimpi,

как то очень сложно
я бы написал так:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
SELECT Id, Value
FROM 
	(
	SELECT *, DENSE_RANK() OVER (ORDER BY R) As RR
	FROM
		(
		SELECT *, id - ROW_NUMBER() OVER (ORDER BY id) As R
		FROM @data
		WHERE Value =  10  --искомая величина
		) As QR
	) As QRR
WHERE RR =  1  --номер группы
...
Рейтинг: 0 / 0
Выборка первой группы записей
    #37357699
stimpi
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
няка,

это если у вас айдентити без гапов )

на таком списке
id value1 52 53 54 106 107 108 59 510 511 1012 1013 1014 515 516 5

выдаст только
id value4 10
...
Рейтинг: 0 / 0
Выборка первой группы записей
    #37357710
няка
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
stimpi,

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

роунамбер на роунамбер
...
Рейтинг: 0 / 0
Выборка первой группы записей
    #37357859
няка
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
stimpi,

http://www.youtube.com/watch?v=iOnHtPHiCLw
...
Рейтинг: 0 / 0
Выборка первой группы записей
    #37357877
AlexMAS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Спасибо всем за советы.

Соглашусь, что в поставленной выше задаче, скорей, самым "простым" решением будет какой-нибудь запрос с подзапросом с использованием функции ROW_NUMBER(). Думаю, в данном варианте проще (наглядней, читабельней) будет анализировать две соседних записи и искать точки "разрыва", как предлагал в самом начале ViPRos.

>> так автор условие на упорядочивание данных ваще не описал

У каждой записи со значением есть идентификатор. Можно считать, что он identity, но там есть gap's, поскольку в оригинальной задачи записи упорядочены по времени создания.


Я, скорей, допустил небольшую неточность в постановке задачи, т.к. хотел ее сделать более общей. В частности попросил выбрать первую группу записей со значением "10". Возможно, задача покажется более интересной, если я добавлю немного деталей...

На самом деле все эти записи - это данные от некоторого датчика. Грубо говоря, в таблице базы данных хранится последовательность сигналов в виде, а сама таблица имеет вид вроде этого:

declare @signals table (Time datetime, Value float)

Суть в том, что из всей последовательности таких сигналов нужно выбрать группы, значение которых превышает определенных порог (~ удовлетворяет некоторым критериям, которые в дальнейшем могут изменяться). Если условиться, что порог равен 10, то в следующем наборе:

..., 2, 3, 1, 2, 5, 3, 10 , 11 , 15 , 1, 2, 2, 12 , 14 , 10 , 1, 0, 2, ...

нужно выбрать 2 группы: (10, 11, 15) и (12, 14, 10). Вместе с этим есть потребность выбрать только первую группу, например, начиная с указанного времени. Как раз эта задача и была поставлена в самом начале.

Критерий выбора группы - это какое-то бизнес-правило, которое будет инкапсулировать какая-нибудь спецификация. С этим все понятно. Сейчас меня по большей части волнует вопрос производительности: как лучше - загрузить список и проанализировать или написать "хитрый" запрос... Пока склоняюсь к первому варианту.
...
Рейтинг: 0 / 0
Выборка первой группы записей
    #37357895
няка
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
AlexMAS,

гапсы устранить еще одним роунамбером не проблема, как я уже написал

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
SELECT Id, Value
FROM 
	(
	SELECT *, DENSE_RANK() OVER (ORDER BY R) As RR
	FROM
		(
		SELECT *, rId - ROW_NUMBER() OVER (ORDER BY id) As R
		FROM 
			(
			SELECT *, ROW_NUMBER() OVER (ORDER BY id) As rId
			FROM @data
			) As BQ
		WHERE Value between  10  and  20  --диаппазон величин
		) As QR
	) As QRR
WHERE RR =  1  --номер группы

насчет производительности хз, если это критично, то нада тестить
...
Рейтинг: 0 / 0
Выборка первой группы записей
    #37358095
stimpi
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
посмотрите тему 10818697

вот так еще можно

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
select resD.*
from @data resD
join (
select tt.*, ROW_NUMBER() OVER(ORDER BY startid) row_num
from (select d.Id startid, d.Value, isnull(t.id, (select MAX(id) +  1  from @data)) as endid
      from @data d
        outer apply (select id, value from @data d1 
                     where d1.id > d.id
                      and d1.value <>  10 
                      and not exists (select *
                                      from @data d2
                                      where d2.Value <>  10 
                                        and d2.Id > d.Id and d2.id < d1.Id)) t
      where d.Value =  10 ) TT) ttt on resD.Id >= ttt.startid and resD.id < ttt.endid
where ttt.row_num =  1 
...
Рейтинг: 0 / 0
Выборка первой группы записей
    #37358316
няка
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
stimpi,

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

мы не ищем легких путей )

Надо бы ваш вариант на профпригодность (быстродействие) проверить на больших объемах данных
...
Рейтинг: 0 / 0
Выборка первой группы записей
    #37358974
няка
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
stimpi,

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

тестовые данные на 100000 записей

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
declare @data table (Id int identity, Value int)

;with cte_Numbers (Value)
AS
(
select  1  AS Value union all  select Value +  1  from cte_Numbers where Value <  100000 
) 

insert into @data
select Value - Value %  5  from cte_Numbers option (MAXRECURSION  0 )

без индекса по айдихе
няка(ms) stimpi(ms)140-200 40-70

с индексом по айдихе
няка(ms) stimpi(ms)20-30 20-30

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

спасибо, интересный результат
я когда писал что ваш метод быстрее, имел ввиду без индексов, оно так и получилось
с индексами порой не так просто на вскидку сказать каков будет результат
...
Рейтинг: 0 / 0
25 сообщений из 25, страница 1 из 1
Форумы / ADO.NET, LINQ, Entity Framework, NHibernate, DAL, ORM [игнор отключен] [закрыт для гостей] / Выборка первой группы записей
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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