Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
Топик располагается на нескольких страницах: [1] 2 3   вперед  Ctrl      все
 Как выбрать записив этом примере?  [new]
Ролг Хупин
Member

Откуда: Чебаркуль
Сообщений: 4183
Как красиво сделать запрос? Реально - тбалица большая, и полей больше, чем 8.
Можно, конечно, перечислить все варианты в вхере, но возможно есть вариант попотимальнее

Есть таблица, надо выбрать все записи, у которых есть пары ((p1,p2), (p3,p4), (p5,p6), (p7,p8)) со значениями не 0, такие пары должны идти подряд, если есть "дырка" (например, (p1,p2), (0,0), (p5,p6)) - не попадают в выборку, и начинаться должны с не 0, т.е. всегда в выборке (p1,p2)<>0

Например, здесь должны выбраться записи 3,5,7,8
declare @t table(id int, p1 int, p2 int, p3 int, p4 int, p5 int, p6 int, p7 int, p8 int)

insert into @t(id, p1, p2, p3, p4,p5, p6, p7, p8)
select 1, 0,0,0,0, 0,0,0,0
union all
select 2, 1,0,0,0, 0,0,0,0
union all
select 3, 1,1,0,0, 0,0,0,0
union all
select 4, 1,1,1,0, 0,0,0,0
union all
select 5, 1,1,1,1, 0,0,0,0
union all
select 6, 1,1,1,1, 0,0,1,1
union all
select 7, 1,1,1,1, 1,1,0,0
union all
select 8, 1,1,1,1, 1,1,1,1
union all
select 9, 1,1,0,0, 1,1,0,0
union all
select 10, 1,1,0,0, 1,0,0,0
union all
select 11, 0,0,1,1, 1,1,0,0
union all
select 12, 0,0,1,1, 0,0,1,1
union all
select 13, 1,1,0,1, 0,0,0,0
union all
select 14, 1,1,0,0, 0,0,1,1
10 мар 17, 11:55    [20280918]     Ответить | Цитировать Сообщить модератору
 Re: Как выбрать записив этом примере?  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 8826
Выбирайте по нечетным колонкам = 1, т.к. четные несущественны.
10 мар 17, 12:12    [20281059]     Ответить | Цитировать Сообщить модератору
 Re: Как выбрать записив этом примере?  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 8826
На самом деле Вы нарушаете суть реляционной таблицы, т.к. последовательность атрибутов не должна иметь значения.
10 мар 17, 12:14    [20281069]     Ответить | Цитировать Сообщить модератору
 Re: Как выбрать записив этом примере?  [new]
Кесарь
Member

Откуда:
Сообщений: 677
Если в задании сказано, что кол-во столбцов переменное, то вам намекают на необходимость транспонирования таблицы. Ищите по ключевому слову PIVOT TABLE.
10 мар 17, 12:18    [20281097]     Ответить | Цитировать Сообщить модератору
 Re: Как выбрать записив этом примере?  [new]
Ролг Хупин
Member

Откуда: Чебаркуль
Сообщений: 4183
Кесарь
Если в задании сказано, что кол-во столбцов переменное, то вам намекают на необходимость транспонирования таблицы. Ищите по ключевому слову PIVOT TABLE.


Возможно, я выразился не конкретно.
Количество столбцов фиксировано, в реале = 32, в примере я уменьшил для простоты.
10 мар 17, 12:23    [20281129]     Ответить | Цитировать Сообщить модератору
 Re: Как выбрать записив этом примере?  [new]
Ролг Хупин
Member

Откуда: Чебаркуль
Сообщений: 4183
Владислав Колосов
На самом деле Вы нарушаете суть реляционной таблицы, т.к. последовательность атрибутов не должна иметь значения.


согласен, но в данном случае так было сделано, и в физическом процессе - это существенно: пары, без дырок
10 мар 17, 12:24    [20281138]     Ответить | Цитировать Сообщить модератору
 Re: Как выбрать записив этом примере?  [new]
Massa52
Member

Откуда:
Сообщений: 388
Ролг Хупин,
Здесь напрашивается аналогия с комплексными чилами или многомерная фигура.
И решение должно идти оттуда.
10 мар 17, 12:34    [20281207]     Ответить | Цитировать Сообщить модератору
 Re: Как выбрать записив этом примере?  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 8826
Ролг Хупин,

данные должны быть сохранены в таком виде:
таблица1
группаподгруппазначение
511
521
530
540
611
621
630
641
1311
1320
1330
1340

таблица2
группаподгруппазначение
511
521
530
540
611
621
630
641
1311
1321
1330
1340


По этом данным написать запрос с проверкой "пустых" интервалов в последовательностях подгрупп.
10 мар 17, 12:36    [20281234]     Ответить | Цитировать Сообщить модератору
 Re: Как выбрать записив этом примере?  [new]
Ролг Хупин
Member

Откуда: Чебаркуль
Сообщений: 4183
Владислав Колосов
Ролг Хупин,

данные должны быть сохранены в таком виде:
таблица1
группаподгруппазначение
511
521
530
540
611
621
630
641
1311
1320
1330
1340

таблица2
группаподгруппазначение
511
521
530
540
611
621
630
641
1311
1321
1330
1340


По этом данным написать запрос с проверкой "пустых" интервалов в последовательностях подгрупп.



понимаю, но данные уже сохранены в том виде, как я привел в примере
Да и таблица реальная, с миллионами записей, изменить ее структуру не получится.
10 мар 17, 12:42    [20281296]     Ответить | Цитировать Сообщить модератору
 Re: Как выбрать записив этом примере?  [new]
Добрый Э - Эх
Guest
Ролг Хупин,

сконкатенировать значения в "битовые вектора" и сравнивать bitand-ом при джойне на сгенерированный набор допустимых значений масок.
Но,имхо, копи-паст в помощь - проще запихать кучу условий в WHERE....
10 мар 17, 12:46    [20281335]     Ответить | Цитировать Сообщить модератору
 Re: Как выбрать записив этом примере?  [new]
Ролг Хупин
Member

Откуда: Чебаркуль
Сообщений: 4183
Добрый Э - Эх
Ролг Хупин,

сконкатенировать значения в "битовые вектора" и сравнивать bitand-ом при джойне на сгенерированный набор допустимых значений масок.
Но,имхо, копи-паст в помощь - проще запихать кучу условий в WHERE....


с этого и начал, а дальше сбила с толку извечная тяга к знаниям
10 мар 17, 13:02    [20281470]     Ответить | Цитировать Сообщить модератору
 Re: Как выбрать записив этом примере?  [new]
Ролг Хупин
Member

Откуда: Чебаркуль
Сообщений: 4183
Кесарь
Если в задании сказано, что кол-во столбцов переменное, то вам намекают на необходимость транспонирования таблицы. Ищите по ключевому слову PIVOT TABLE.


в каком виде можно получить результат транспонирования и чем это поможет?
10 мар 17, 13:03    [20281474]     Ответить | Цитировать Сообщить модератору
 Re: Как выбрать записив этом примере?  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 8826
Ролг Хупин,

так преобразуйте, это не непосильная задача.
Реляционные методы можно применять только к реляционным данным.
10 мар 17, 13:11    [20281535]     Ответить | Цитировать Сообщить модератору
 Re: Как выбрать записив этом примере?  [new]
Кесарь
Member

Откуда:
Сообщений: 677
Ролг Хупин
Кесарь
Если в задании сказано, что кол-во столбцов переменное, то вам намекают на необходимость транспонирования таблицы. Ищите по ключевому слову PIVOT TABLE.


в каком виде можно получить результат транспонирования и чем это поможет?


С миллионами строк не поможет :) Вы просто нечётко сказали с самого начала, какой у вас случай.
10 мар 17, 13:12    [20281537]     Ответить | Цитировать Сообщить модератору
 Re: Как выбрать записив этом примере?  [new]
invm
Member

Откуда: Москва
Сообщений: 9836
+ "В лоб"
declare @t table(id int, p1 int, p2 int, p3 int, p4 int, p5 int, p6 int, p7 int, p8 int);

insert into @t(id, p1, p2, p3, p4,p5, p6, p7, p8)
select 1, 0,0,0,0, 0,0,0,0
union all
select 2, 1,0,0,0, 0,0,0,0
union all
select 3, 1,1,0,0, 0,0,0,0
union all
select 4, 1,1,1,0, 0,0,0,0
union all
select 5, 1,1,1,1, 0,0,0,0
union all
select 6, 1,1,1,1, 0,0,1,1
union all
select 7, 1,1,1,1, 1,1,0,0
union all
select 8, 1,1,1,1, 1,1,1,1
union all
select 9, 1,1,0,0, 1,1,0,0
union all
select 10, 1,1,0,0, 1,0,0,0
union all
select 11, 0,0,1,1, 1,1,0,0
union all
select 12, 0,0,1,1, 0,0,1,1
union all
select 13, 1,1,0,1, 0,0,0,0
union all
select 14, 1,1,0,0, 0,0,1,1;

declare @masks table (m varchar(8));
insert into @masks
values
 ('11000000'), ('11110000'), ('11111100'), ('11111111');

select
 t.*
from
 @t t cross apply
 (
  select
   case when p1 = 0 then '0' else '1' end +
   case when p2 = 0 then '0' else '1' end +
   case when p3 = 0 then '0' else '1' end +
   case when p4 = 0 then '0' else '1' end +
   case when p5 = 0 then '0' else '1' end +
   case when p6 = 0 then '0' else '1' end +
   case when p7 = 0 then '0' else '1' end +
   case when p8 = 0 then '0' else '1' end
 ) as a(m) join
 @masks m on m.m = a.m;
10 мар 17, 13:40    [20281734]     Ответить | Цитировать Сообщить модератору
 Re: Как выбрать записив этом примере?  [new]
Кесарь
Member

Откуда:
Сообщений: 677
Ролг Хупин
Как красиво сделать запрос? Реально - тбалица большая, и полей больше, чем 8.
Можно, конечно, перечислить все варианты в вхере, но возможно есть вариант попотимальнее

Есть таблица, надо выбрать все записи, у которых есть пары ((p1,p2), (p3,p4), (p5,p6), (p7,p8)) со значениями не 0, такие пары должны идти подряд, если есть "дырка" (например, (p1,p2), (0,0), (p5,p6)) - не попадают в выборку, и начинаться должны с не 0, т.е. всегда в выборке (p1,p2)<>0

Например, здесь должны выбраться записи 3,5,7,8
declare @t table(id int, p1 int, p2 int, p3 int, p4 int, p5 int, p6 int, p7 int, p8 int)

insert into @t(id, p1, p2, p3, p4,p5, p6, p7, p8)
select 1, 0,0,0,0, 0,0,0,0
union all
select 2, 1,0,0,0, 0,0,0,0
union all
select 3, 1,1,0,0, 0,0,0,0
union all
select 4, 1,1,1,0, 0,0,0,0
union all
select 5, 1,1,1,1, 0,0,0,0
union all
select 6, 1,1,1,1, 0,0,1,1
union all
select 7, 1,1,1,1, 1,1,0,0
union all
select 8, 1,1,1,1, 1,1,1,1
union all
select 9, 1,1,0,0, 1,1,0,0
union all
select 10, 1,1,0,0, 1,0,0,0
union all
select 11, 0,0,1,1, 1,1,0,0
union all
select 12, 0,0,1,1, 0,0,1,1
union all
select 13, 1,1,0,1, 0,0,0,0
union all
select 14, 1,1,0,0, 0,0,1,1


Решение: надо создать и хранить техническое поле - флаг входа в выборку. По нему отсекать нулевые наборы и наборы заранее не подходящие для вывода, т.е. с нечётными контрольными суммами столбцов. Это нужно для уменьшения нагрузки при большом количестве данных и запросов. Один раз просчитываете техническое поле, потом выбираете по нему сколько хотите, накладные расходы меньше при большом кол-ве запросов.

Далее выборка по строке, в которой есть вхождение подстроки "01"...


--alter table [@t] add s int
update @t set
 s = (p1 + p2 + p3 + p4 + p5 + p6 + p7 + p8)

update @t set
 s = (case when s > 0 then s%2
           when s = 0 then 1 else 1 end)

select tt.id, stri
from (select t.id, convert(char(1), p1) + convert(char(1), p2) + convert(char(1), p3) + convert(char(1), p4)
		+ convert(char(1), p5) + convert(char(1), p6) + convert(char(1), p7) + convert(char(1), p8) as stri
	  from @t t
	  where t.s = 0) tt
where CHARINDEX('01', stri) = 0
order by tt.id
10 мар 17, 13:44    [20281769]     Ответить | Цитировать Сообщить модератору
 Re: Как выбрать записив этом примере?  [new]
Massa52
Member

Откуда:
Сообщений: 388
Ролг Хупин,

Или 8 бит в число от 0 до 255
select *,p8+p7*2+p6*4+p5*8+p4*16+p3*32+p2*64+p1*128 AS c from @t
10 мар 17, 13:57    [20281862]     Ответить | Цитировать Сообщить модератору
 Re: Как выбрать записив этом примере?  [new]
Massa52
Member

Откуда:
Сообщений: 388
А можно пары преобразовать в число от 0-3
(p1,p2)<>0 эквивалентно 3
10 мар 17, 14:04    [20281911]     Ответить | Цитировать Сообщить модератору
 Re: Как выбрать записив этом примере?  [new]
Massa52
Member

Откуда:
Сообщений: 388
Получается - число 2^32
Для этого набора чисел сгенерить таблицу которую надо выбирать(числа без дырок).
А из исходных данных пар генерить вычисляемое поле как показано выше для 8 бит.
А потом жоинить их.
10 мар 17, 14:17    [20281997]     Ответить | Цитировать Сообщить модератору
 Re: Как выбрать записив этом примере?  [new]
Massa52
Member

Откуда:
Сообщений: 388
А если разбивать по парам и ставить в соответствие паре число 0-3
А эти пары преобразовать в 10-е числа то получаем - что нам нужны только следующие выборки:

3000
3300
3330
3333

3033
3030
10 мар 17, 15:36    [20282529]     Ответить | Цитировать Сообщить модератору
 Re: Как выбрать записив этом примере?  [new]
Ролг Хупин
Member

Откуда: Чебаркуль
Сообщений: 4183
invm
+ "В лоб"
declare @t table(id int, p1 int, p2 int, p3 int, p4 int, p5 int, p6 int, p7 int, p8 int);

insert into @t(id, p1, p2, p3, p4,p5, p6, p7, p8)
select 1, 0,0,0,0, 0,0,0,0
union all
select 2, 1,0,0,0, 0,0,0,0
union all
select 3, 1,1,0,0, 0,0,0,0
union all
select 4, 1,1,1,0, 0,0,0,0
union all
select 5, 1,1,1,1, 0,0,0,0
union all
select 6, 1,1,1,1, 0,0,1,1
union all
select 7, 1,1,1,1, 1,1,0,0
union all
select 8, 1,1,1,1, 1,1,1,1
union all
select 9, 1,1,0,0, 1,1,0,0
union all
select 10, 1,1,0,0, 1,0,0,0
union all
select 11, 0,0,1,1, 1,1,0,0
union all
select 12, 0,0,1,1, 0,0,1,1
union all
select 13, 1,1,0,1, 0,0,0,0
union all
select 14, 1,1,0,0, 0,0,1,1;

declare @masks table (m varchar(8));
insert into @masks
values
 ('11000000'), ('11110000'), ('11111100'), ('11111111');

select
 t.*
from
 @t t cross apply
 (
  select
   case when p1 = 0 then '0' else '1' end +
   case when p2 = 0 then '0' else '1' end +
   case when p3 = 0 then '0' else '1' end +
   case when p4 = 0 then '0' else '1' end +
   case when p5 = 0 then '0' else '1' end +
   case when p6 = 0 then '0' else '1' end +
   case when p7 = 0 then '0' else '1' end +
   case when p8 = 0 then '0' else '1' end
 ) as a(m) join
 @masks m on m.m = a.m;


Спасибо всем участникам!

Спасибо, invm, хорошее решение, а главное - красивое (ц)
10 мар 17, 15:38    [20282544]     Ответить | Цитировать Сообщить модератору
 Re: Как выбрать записив этом примере?  [new]
Massa52
Member

Откуда:
Сообщений: 388
declare @t table(id int, p1 int, p2 int, p3 int, p4 int, p5 int, p6 int, p7 int, p8 int)

insert into @t(id, p1, p2, p3, p4,p5, p6, p7, p8)
select 1, 0,0,0,0, 0,0,0,0
union all
select 2, 1,0,0,0, 0,0,0,0
union all
select 3, 1,1,0,0, 0,0,0,0
union all
select 4, 1,1,1,0, 0,0,0,0
union all
select 5, 1,1,1,1, 0,0,0,0
union all
select 6, 1,1,1,1, 0,0,1,1
union all
select 7, 1,1,1,1, 1,1,0,0
union all
select 8, 1,1,1,1, 1,1,1,1
union all
select 9, 1,1,0,0, 1,1,0,0
union all
select 10, 1,1,0,0, 1,0,0,0
union all
select 11, 0,0,1,1, 1,1,0,0
union all
select 12, 0,0,1,1, 0,0,1,1
union all
select 13, 1,1,0,1, 0,0,0,0
union all
select 14, 1,1,0,0, 0,0,1,1

;with x as
(select *, (p1 + p1 + p2)*10*10*10 + (p3 + p3 + p4)*10*10 + (p5 + p5 + p6)*10 + p7 + p7 + p8 as c 
from @t)
select * from x 
where c in (3000, 3300, 3330, 3333)
10 мар 17, 15:55    [20282655]     Ответить | Цитировать Сообщить модератору
 Re: Как выбрать записив этом примере?  [new]
aleks2
Guest
Конкурс на самый идиотский запрос?

declare @t table(id int, p1 int, p2 int, p3 int, p4 int, p5 int, p6 int, p7 int, p8 int);

insert into @t(id, p1, p2, p3, p4,p5, p6, p7, p8)
select 1, 0,0,0,0, 0,0,0,0
union all
select 2, 1,0,0,0, 0,0,0,0
union all
select 3, 1,1,0,0, 0,0,0,0
union all
select 4, 1,1,1,0, 0,0,0,0
union all
select 5, 1,1,1,1, 0,0,0,0
union all
select 6, 1,1,1,1, 0,0,1,1
union all
select 7, 1,1,1,1, 1,1,0,0
union all
select 8, 1,1,1,1, 1,1,1,1
union all
select 9, 1,1,0,0, 1,1,0,0
union all
select 10, 1,1,0,0, 1,0,0,0
union all
select 11, 0,0,1,1, 1,1,0,0
union all
select 12, 0,0,1,1, 0,0,1,1
union all
select 13, 1,1,0,1, 0,0,0,0
union all
select 14, 1,1,0,0, 0,0,1,1;


select t.* from @t t 
 where not exists ( select * 
                      from ( select *, p_ = lead(p,1,0) over(order by n)
                                from
					                ( select n = 0, p = p1
							          union all
							          select n = 1, p = p2
							          union all
							          select n = 2, p = p3
							          union all
							          select n = 3, p = p4
							          union all
							          select n = 4, p = p5
							          union all
							          select n = 5, p = p6
							          union all
							          select n = 6, p = p7
							          union all
							          select n = 7, p = p8
						        ) as ps
                        ) as x
                    where p < p_ or ( n%2 = 0 and p = 1 and p_ = 0)
)
10 мар 17, 16:41    [20282863]     Ответить | Цитировать Сообщить модератору
 Re: Как выбрать записив этом примере?  [new]
Massa52
Member

Откуда:
Сообщений: 388
aleks2,
для меня это решение - вынос мозга.
Смотрел, смотрел - так и не понял.

+ идиотские рассуждения к постановке задачи:
Нафига хранить 8 отдельных полей да еще миллионами - когда достаточно одно вычисляемое поле.
Из этого поля всегда можно однозначно восстановить все 8.
10 мар 17, 16:56    [20282942]     Ответить | Цитировать Сообщить модератору
 Re: Как выбрать записив этом примере?  [new]
Ролг Хупин
Member

Откуда: Чебаркуль
Сообщений: 4183
Massa52
aleks2,
для меня это решение - вынос мозга.
Смотрел, смотрел - так и не понял.

+ идиотские рассуждения к постановке задачи:
Нафига хранить 8 отдельных полей да еще миллионами - когда достаточно одно вычисляемое поле.
Из этого поля всегда можно однозначно восстановить все 8.


Я привел упрощенный пример, но вы, коллеги, естественно, вольны упражняться в эитетах об "идиотскости" и т,д.
Некоторым это улучшает самооценку и самочувствие.
10 мар 17, 18:08    [20283223]     Ответить | Цитировать Сообщить модератору
Топик располагается на нескольких страницах: [1] 2 3   вперед  Ctrl      все
Все форумы / Microsoft SQL Server Ответить