powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Выборка по групповым фильтрам (простой вопрос Знатокам SQL по обычному Select)
19 сообщений из 19, страница 1 из 1
Выборка по групповым фильтрам (простой вопрос Знатокам SQL по обычному Select)
    #39598999
ВладимирЛ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Добрый день, Знатоки SQL!

Сейчас в интернете часто встречается использование групповых (или сгруппированных) фильтров.
Как по ним организовать выборку? Вот максимально упрощённый вариант T-SQL кода:

Код: sql
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.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
--Главная таблица
Declare @tbMain table
(idMain int,   
 p1 int,
 p2 int )

			 Insert into @tbMain (idMain, p1,p2)
				  values (1,    100, 2017),
						 (2,    100, 2017),
						 (3,    200, 2017),
						 (4,    200, 2018)


--Таблица Фильтр
Declare @tbFilter table
		(idFilter int,  
		 nameFilter nvarchar(10),
		 value int)

			 Insert into @tbFilter (idFilter, nameFilter, value)
				  values (10,   'Код',100),
						 (20,   'Код',200),
						 (30,   'Год',2017),
						 (40,   'Год',2018)

--Таблица для связи (многие ко многим) Главной Таблицы и Таблицы Фильтра
Declare @tbManyToMany table
		(id int  identity (1,1),
		 idMain int,
		 idFilter int)

			 Insert into @tbManyToMany (idMain, idFilter)
				  values (1, 10),  --Фильтр по коду
                         (2, 10),  --Фильтр по коду
                         (3, 20),  --Фильтр по коду
                         (4, 20),  --Фильтр по коду

                         (1, 30),  --Фильтр по Году
                         (2, 30),  --Фильтр по Году
                         (3, 30),  --Фильтр по Году
                         (4, 40)   --Фильтр по Году


--Задаем Фильтр:
--Код   -> Указываем 100 и 200
--Год   -> Указываем 2017
--Результат должен быть   <Select * From @tbMain...+ where ...???>:
			--1	100	2017
			--2	100	2017
			--3	200	2017



--Вопрос - Как составить запрос в один запрос? Решается ли задача в один запрос?
--Пробовал варианты, но увы-ссс:



Select M.* From @tbMain As M
           inner join @tbManyToMany as MM on M.idMain = MM.idMain
		      inner join @tbFilter F on MM.idFilter = F.idFilter
where 
            (F.nameFilter = 'Код' and  F.value in (100, 200) )
			or --??? and ???
			(F.nameFilter = 'Год' and  F.value in (2017) )
...
Рейтинг: 0 / 0
Выборка по групповым фильтрам (простой вопрос Знатокам SQL по обычному Select)
    #39599035
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ВладимирЛКак составить запрос в один запрос? Решается ли задача в один запрос?
Схематично:
Код: sql
1.
2.
3.
4.
5.
6.
SELECT m.*
FROM main m
JOIN properties p
WHERE (p.type, p.value) IN ( ('type1', 'value1'), .. , ('typeN', 'valueN') )
GROUP BY m.*
HAVING COUNT(*) = N
...
Рейтинг: 0 / 0
Выборка по групповым фильтрам (простой вопрос Знатокам SQL по обычному Select)
    #39599068
ВладимирЛ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Akina, Уточнение-вопрос:
Конструкция

WHERE (p.type, p.value) IN ( ('type1', 'value1'), .. , ('typeN', 'valueN') )

вроде как не из T-SQL?
В "транзакте" с левой стороны IN допускается только один параметр(?).
...
Рейтинг: 0 / 0
Выборка по групповым фильтрам (простой вопрос Знатокам SQL по обычному Select)
    #39599069
iap
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
AkinaВладимирЛКак составить запрос в один запрос? Решается ли задача в один запрос?
Схематично:
Код: sql
1.
2.
3.
4.
5.
6.
SELECT m.*
FROM main m
JOIN properties p
WHERE (p.type, p.value) IN ( ('type1', 'value1'), .. , ('typeN', 'valueN') )
GROUP BY m.*
HAVING COUNT(*) = N

В T-SQL так нельзя.
Однако, есть же EXISTS() и INTERSECT
...
Рейтинг: 0 / 0
Выборка по групповым фильтрам (простой вопрос Знатокам SQL по обычному Select)
    #39599073
iap
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
iapОднако, есть же EXISTS() и INTERSECTМожет, даже NOT EXISTS(SELECT ... EXCEPT SELECT ... EXCEPT SELECT .........)
...
Рейтинг: 0 / 0
Выборка по групповым фильтрам (простой вопрос Знатокам SQL по обычному Select)
    #39599088
ВладимирЛ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
iap,
Вот так сработало:
Select M.* From @tbMain As M
inner join @tbManyToMany as MM on M.idMain = MM.idMain
inner join @tbFilter F on MM.idFilter = F.idFilter
where
(F.nameFilter = 'Код' and F.value in (100, 200) )
INTERSECT
Select M.* From @tbMain As M
inner join @tbManyToMany as MM on M.idMain = MM.idMain
inner join @tbFilter F on MM.idFilter = F.idFilter
where

(F.nameFilter = 'Год' and F.value in (2017) )

Но здесь все-таки два SELECT, а как в одном?
...
Рейтинг: 0 / 0
Выборка по групповым фильтрам (простой вопрос Знатокам SQL по обычному Select)
    #39599093
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ВладимирЛКонструкция
Код: sql
1.
WHERE (p.type, p.value) IN ( ('type1', 'value1'), .. , ('typeN', 'valueN') )


вроде как не из T-SQL?
Вам слово "схематично" ни о чём не говорит? и да, в T-SQL это развернётся в показанное Вами же
ВладимирЛ
Код: sql
1.
2.
3.
4.
where 
(F.nameFilter = 'Код' and  F.value in (100, 200) )
or --??? and ???
(F.nameFilter = 'Год' and  F.value in (2017) )
...
Рейтинг: 0 / 0
Выборка по групповым фильтрам (простой вопрос Знатокам SQL по обычному Select)
    #39599097
iap
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ВладимирЛ,

можно же переписать запрос Akina с помощью явного сравнения пар type и value и операторов AND и OR.
Длинное будет условие, зато SELECT - один!
...
Рейтинг: 0 / 0
Выборка по групповым фильтрам (простой вопрос Знатокам SQL по обычному Select)
    #39599116
ВладимирЛ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Akina,
Да, спасибо за ответ. На "схематично" я, конечно, обратил внимание. Но если бы все было так просто, я бы не задавал вопрос.
Упрощаем запрос до одной таблицы:

Select M.* From @tbMain As M
where p1 in (100,200)
and p2 in (2017)

И вот так работает, поскольку условие наложено на два поля таблицы.
А в том, что я написал - условие накладывается на (схематично) одно поле, поэтому по or оно возвращает больше, чем надо, а по and вообще ничего не возвращает. То есть, опять же схематично - сначала должен отработать первый фильтр, а потом на его результат належится следующий фильтр. Как это сделать одним SELECTом я не знаю. Возможно, задача не решаема.






Там нюанс в том, что используется
...
Рейтинг: 0 / 0
Выборка по групповым фильтрам (простой вопрос Знатокам SQL по обычному Select)
    #39599137
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ВладимирЛпо or оно возвращает больше, чем надоТо есть группировку и пост-отбор Вы в моей схеме не увидели? а именно они обеспечивают решение задачи.
...
Рейтинг: 0 / 0
Выборка по групповым фильтрам (простой вопрос Знатокам SQL по обычному Select)
    #39599152
ВладимирЛ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Akina,

Ну вот запрос с группировкой:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
Select M.idMain, M.p1, M.p2 From @tbMain As M
           inner join @tbManyToMany as MM on M.idMain = MM.idMain
		      inner join @tbFilter F on MM.idFilter = F.idFilter
where 
            (F.nameFilter = 'Код' and  F.value in (100, 200) )
			or --??? and ???
			(F.nameFilter = 'Год' and  F.value in (2017) )
group by  M.idMain, M.p1, M.p2




Возвращает:

1 100 2017
2 100 2017
3 200 2017
4 200 2018


А годик то указан 2017 ???? Вот в этом и заковыка.
...
Рейтинг: 0 / 0
Выборка по групповым фильтрам (простой вопрос Знатокам SQL по обычному Select)
    #39599156
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Нет, вот что Вы хотите, если у Вас в списке вывода - уникальный индекс???
...
Рейтинг: 0 / 0
Выборка по групповым фильтрам (простой вопрос Знатокам SQL по обычному Select)
    #39599158
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да и HAVING я как-то не наблюдаю...
...
Рейтинг: 0 / 0
Выборка по групповым фильтрам (простой вопрос Знатокам SQL по обычному Select)
    #39599179
ВладимирЛ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Akina,
Без "ключа" вот так:
100 2017
200 2017
200 2018

то есть 2018 все равно есть, поэтому "оно" не принципиально.
А что даёт это условие:

HAVING COUNT(*) = N

в частности я не совсем понимаю параметр N. (в T-SQL такого нет)
...
Рейтинг: 0 / 0
Выборка по групповым фильтрам (простой вопрос Знатокам SQL по обычному Select)
    #39599231
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ВладимирЛв частности я не совсем понимаю параметр NОбрати внимание на условие отбора - там указаны наборы условий с номерами от 1 до N. Вот это N и должно быть в запросе.
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
Select M.p1, M.p2 
From @tbMain As M
inner join @tbManyToMany as MM on M.idMain = MM.idMain
inner join @tbFilter F on MM.idFilter = F.idFilter
where (F.nameFilter = 'Код' and  F.value in (100, 200) ) -- условие по первому параметру
   or
      (F.nameFilter = 'Год' and  F.value in (2017) ) -- условие по второму параметру
group by  M.p1, M.p2
HAVING COUNT(*) = 2 -- всего параметров - два
...
Рейтинг: 0 / 0
Выборка по групповым фильтрам (простой вопрос Знатокам SQL по обычному Select)
    #39599254
ВладимирЛ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Akina, Спасибо за ответ, осмысливаю. Вообще то -
COUNT(*) - это количество записей по возвращаемым строкам группировки и как оно связано с номером условий? В общем пока непонятно, осмысливаю.
...
Рейтинг: 0 / 0
Выборка по групповым фильтрам (простой вопрос Знатокам SQL по обычному Select)
    #39599261
Фотография Akina
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ВладимирЛкак оно связано с номером условий?не с номером, а с их количеством. Тебе же надо, чтобы запись соответствовала ВСЕМ фильтрам? COUNT(*) тебе как раз и показывает, сколько фильтров из всех соответствуют.
...
Рейтинг: 0 / 0
Выборка по групповым фильтрам (простой вопрос Знатокам SQL по обычному Select)
    #39599272
ВладимирЛ
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Akina,
Вот запрос:

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
Select 
 M.p1, M.p2
 , COUNT(*) as count
  From @tbMain As M
           inner join @tbManyToMany as MM on M.idMain = MM.idMain
		      inner join @tbFilter F on MM.idFilter = F.idFilter
where 
            (F.value in (100, 200) )
		     or --??? and ???
			(F.value in (2017) )
group by  
 M.p1, M.p2
  -- HAVING COUNT(*) = 2




Вот его результат:

100 2017 4
200 2017 2
200 2018 1

Правый столбец - это и есть количество возвращаемых записей по группировке "M.p1, M.p2". С количеством условий вроде как никак не связано.
...
Рейтинг: 0 / 0
Выборка по групповым фильтрам (простой вопрос Знатокам SQL по обычному Select)
    #39600697
Фотография Maxx
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
select t1.*
from @tbMain t1
 inner join @tbFilter f1 on t1.p1 =f1.value
 inner join @tbFilter f2 on f2.value =t1.p2
where f1.nameFilter =N'Код'
  and f2.nameFilter = N'Год'
  and t1.p2 =2017
  and t1.p1 in (100,200)
  and exists (
      select 1
	  from @tbManyToMany
	  where t1.idMain =idMain
	    and ISNULL(f1.idFilter,f2.idFilter) = idFilter
  )
...
Рейтинг: 0 / 0
19 сообщений из 19, страница 1 из 1
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Выборка по групповым фильтрам (простой вопрос Знатокам SQL по обычному Select)
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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