powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Сравнение со списком значений. Как будет правильно?
6 сообщений из 6, страница 1 из 1
Сравнение со списком значений. Как будет правильно?
    #39849424
uaggster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Недавно, роясь в нашем окаменелом дерьме исследуя наследие великих, обнаружил несколько скалярных функций вот такого типа:


Код: 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.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
CREATE FUNCTION [dbo].[IsPlace](@value [nvarchar](255))
RETURNS [int] WITH EXECUTE AS CALLER
AS 
BEGIN
    Declare @yes int;

    SELECT @yes=
	   Case 
			When @value like '% поселок' then 1
			when @value like '% пос' then 1
			When @value like '% пос.' then 1
			When @value like '% п' then 1
			When @value like '% п.' then 1
			When @value like '% п-к.' then 1
			When @value like '% п-к' then 1
			When @value like '% рп' then 1
			When @value like '% рп.' then 1
			When @value like '% р-п' then 1
			When @value like '% раб.п.' then 1
			When @value like '% раб-п' then 1
			When @value like '% кп' then 1
			When @value like '% кп.' then 1
			When @value like '% дп'  then 1
			When @value like '% массив'  then 1
			When @value like '% нп' then 1
			When @value like '% нп.' then 1
			When @value like '% дп' then 1
			When @value like '% дп.' then 1
			When @value like '% округ' then 1
			When @value like '% дачи' then 1
			When @value like '% мкр' then 1 
			When @value like '% мкр.' then 1 

			When @value like '% село' then 1
			when @value like '% с.' then 1
			When @value like '% с' then 1
			When @value like '% с/с' then 1
			When @value like '% с\с' then 1
	   
			when @value like '% ч.' then 1
			When @value like '% ч' then 1
		   
			When @value like '% совхоз' then 1
			When @value like '% свх' then 1
			When @value like '% свх.' then 1
			When @value like '% с-з' then 1
			When @value like '% с/з' then 1
			When @value like '% с\з' then 1

			When @value like '% с/п' then 1
			When @value like '% с/о' then 1

			When @value like '% село' then 1
			when @value like '% с.' then 1
			When @value like '% с' then 1
			When @value like '% сл' then 1
			When @value like '% сл.' then 1

			When @value like '% деревня' then 1
			When @value like '% дер' then 1
			When @value like '% дер.' then 1
			When @value like '% д.' then 1
			When @value like '% д' then 1

			When @value like '% хутор' then 1
			When @value like '% хут' then 1
			When @value like '% хут.' then 1
			When @value like '% х.' then 1
			When @value like '% х' then 1

			When @value like '% пгт' then 1
			When @value like '% пгт.' then 1
			When @value like '% птг' then 1
			When @value like '% птг.' then 1

			When @value like '% станица' then 1 
			When @value like '% ст-ца' then 1 
			When @value like '% ст' then 1 
			When @value like '% ст.' then 1 
			When @value like '% с/т' then 1 
			When @value like '% с\т' then 1 

			When @value like '% станция' then 1
			When @value like '% п/ст' then 1

			When @value like '% аул' then 1
			When @value like '% а' then 1
			When @value like '% а.' then 1

			When @value like '% снт' then 1
			When @value like '% разъезд' then 1
			When @value like '% Учхоз' then 1
			When @value like '% ДНТ' then 1
			When @value like '% ДН/Т' then 1
			When @value like '% пансионат' then 1
			When @value like '% тер' then 1
			When @value like '% тер.' then 1

			When @value like '% городок' then 1
			When @value like '% ЗАТО' then 1

			When @value like '% рзд' then 1

			---------------------------------------------------------------
		   
			When @value like 'поселок %' then 1
			When @value like 'пос %' then 1
			When @value like 'пос.%'  then 1
			When @value like 'п %' then 1
			When @value like 'п.%' then 1
			When @value like 'п-к. %' then 1
			When @value like 'п-к.%' then 1
			When @value like 'рп %' then 1
			When @value like 'р-п %' then 1
			When @value like 'рп.%' then 1
			When @value like 'раб.п.%' then 1
			When @value like 'раб-п%' then 1
			When @value like 'кп %' then 1
			When @value like 'кп.%' then 1
			When @value like 'массив %' then 1
			When @value like 'нп %' then 1
			When @value like 'нп.%' then 1
			When @value like 'дп %' then 1
			When @value like 'дп.%' then 1
			When @value like 'разъезд %' then 1

			When @value like 'село %' then 1
			when @value like 'с.%' then 1
			When @value like 'с %' then 1
			When @value like 'с/с %' then 1
			When @value like 'с\с %' then 1
			When @value like 'сл %' then 1
			When @value like 'сл. %' then 1

			When @value like 'деревня%' then 1
			When @value like 'д. [А-Я][А-Я][А-Я][А-Я]%' then 1
			When @value like 'д [А-Я][А-Я][А-Я][А-Я]%' then 1
			When @value like 'дер %' then 1
			When @value like 'дер.%' then 1

			When @value like 'хутор %' then 1
			When @value like 'хут %' then 1
			When @value like 'хут.%' then 1
			When @value like 'х.%' then 1
			When @value like 'х %' then 1

			When @value like 'пгт %' then 1
			When @value like 'пгт.%' then 1
			When @value like 'птг %' then 1
			When @value like 'птг.%' then 1

			When @value like 'станица%' then 1 
			When @value like 'ст-ца%' then 1 
			When @value like 'ст %' then 1 
			When @value like 'ст.%' then 1
			When @value like 'с/т %' then 1 
			When @value like 'с\т %' then 1
			When @value like 'ж/д%' then 1 

			When @value like 'совхоз %' then 1
			When @value like 'с-з %' then 1
			When @value like 'с/з %' then 1
			When @value like 'с\з %' then 1
			When @value like 'свх %' then 1
			When @value like 'свх.%' then 1
			When @value like 'станция %' then 1
			When @value like 'п/ст %' then 1

			When @value like 'с/п %' then 1
			When @value like 'с/о %' then 1
		   
			When @value like 'аул %' then 1

			when @value like 'ч.%' then 1
			When @value like 'ч %' then 1
			When @value like 'снт. %' then 1
			When @value like 'снт %' then 1
			When @value like 'дп. %'  then 1
			When @value like 'дп %'  then 1
			When @value like 'округ %' then 1
			When @value like 'Учхоз %' then 1
			When @value like 'дачи %' then 1
			When @value like 'ДНТ %' then 1
			When @value like 'ДН/Т %' then 1
			When @value like 'пансионат %' then 1
			When @value like 'тер %' then 1
			When @value like 'тер.%' then 1

			When @value like 'городок %' then 1

			When @value like 'ЗАТО %' then 1

			When @value like 'рзд %' then 1

	   Else 0
	   End
    Return @yes
End




Я хотел уже переписать их так (по прежнему в скалярку, чтобы не ломать логику запросов, которые на них базируются):

Код: 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.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
Select top(1) * 
From 
(
Select 1 yes
Where exists (
	Select 1 
		from (values
	 ('% поселок' )
	,('% пос' )
	,('% пос.' )
	,('% п' )
	,('% п.' )
	,('% п-к.' )
	,('% п-к' )
	,('% рп' )
	,('% рп.' )
	,('% р-п' )
	,('% раб.п.' )
	,('% раб-п' )
	,('% кп' )
	,('% кп.' )
	,('% дп'  )
	,('% массив'  )
	,('% нп' )
	,('% нп.' )
	,('% дп' )
	,('% дп.' )
	,('% округ' )
	,('% дачи' )
	,('% мкр' ) 
	,('% мкр.' ) 
	,('% село' )
	,('% с.' )
	,('% с' )
	,('% с/с' )
	,('% с\с' )
	,('% ч.' )
	,('% ч' )
	,('% совхоз' )
	,('% свх' )
	,('% свх.' )
	,('% с-з' )
	,('% с/з' )
	,('% с\з' )
	,('% с/п' )
	,('% с/о' )
	,('% село' )
	,('% с.' )
	,('% с' )
	,('% сл' )
	,('% сл.' )
	,('% деревня' )
	,('% дер' )
	,('% дер.' )
	,('% д.' )
	,('% д' )
	,('% хутор' )
	,('% хут' )
	,('% хут.' )
	,('% х.' )
	,('% х' )
	,('% пгт' )
	,('% пгт.' )
	,('% птг' )
	,('% птг.' )
	,('% станица' ) 
	,('% ст-ца' ) 
	,('% ст' ) 
	,('% ст.' ) 
	,('% с/т' ) 
	,('% с\т' ) 
	,('% станция' )
	,('% п/ст' )
	,('% аул' )
	,('% а' )
	,('% а.' )
	,('% снт' )
	,('% разъезд' )
	,('% Учхоз' )
	,('% ДНТ' )
	,('% ДН/Т' )
	,('% пансионат' )
	,('% тер' )
	,('% тер.' )
	,('% городок' )
	,('% ЗАТО' )
	,('% рзд' )
	,('поселок %' )
	,('пос %' )
	,('пос.%'  )
	,('п %' )
	,('п.%' )
	,('п-к. %' )
	,('п-к.%' )
	,('рп %' )
	,('р-п %' )
	,('рп.%' )
	,('раб.п.%' )
	,('раб-п%' )
	,('кп %' )
	,('кп.%' )
	,('массив %' )
	,('нп %' )
	,('нп.%' )
	,('дп %' )
	,('дп.%' )
	,('разъезд %' )
	,('село %' )
	,('с.%' )
	,('с %' )
	,('с/с %' )
	,('с\с %' )
	,('сл %' )
	,('сл. %' )
	,('деревня%' )
	,('д. [А-Я][А-Я][А-Я][А-Я]%' )
	,('д [А-Я][А-Я][А-Я][А-Я]%' )
	,('дер %' )
	,('дер.%' )
	,('хутор %' )
	,('хут %' )
	,('хут.%' )
	,('х.%' )
	,('х %' )
	,('пгт %' )
	,('пгт.%' )
	,('птг %' )
	,('птг.%' )
	,('станица%' ) 
	,('ст-ца%' ) 
	,('ст %' ) 
	,('ст.%' )
	,('с/т %' ) 
	,('с\т %' )
	,('ж/д%' ) 
	,('совхоз %' )
	,('с-з %' )
	,('с/з %' )
	,('с\з %' )
	,('свх %' )
	,('свх.%' )
	,('станция %' )
	,('п/ст %' )
	,('с/п %' )
	,('с/о %' )
	,('аул %' )
	,('ч.%' )
	,('ч %' )
	,('снт. %' )
	,('снт %' )
	,('дп. %'  )
	,('дп %'  )
	,('округ %' )
	,('Учхоз %' )
	,('дачи %' )
	,('ДНТ %' )
	,('ДН/Т %' )
	,('пансионат %' )
	,('тер %' )
	,('тер.%' )
	,('городок %' )
	,('ЗАТО %' )
	,('рзд %' )) t(pattern)
Where @value like t.pattern
)
Union all
Select 0
) t



Но призадумался, а будет ли от этого польза и удовольствие?
Т.е. будет ли оно меньше грузить диск, процессор, и вообще- работать быстрее?

Можно ли, не глядя на план :-), сказать, что, например, второе - бест практиз, а первое - нет. Ну и наоборот.
Ну или, может есть совсем правильное решение?
...
Рейтинг: 0 / 0
Сравнение со списком значений. Как будет правильно?
    #39849515
Фотография alexeyvg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
uaggsterЯ хотел уже переписать их так (по прежнему в скалярку, чтобы не ломать логику запросов, которые на них базируются)
Но призадумался, а будет ли от этого польза и удовольствие?
Т.е. будет ли оно меньше грузить диск, процессор, и вообще- работать быстрее?То есть переписать тело скалярки? ИМХО без разницы.

PS Второй вариант выглядит подозрительно, с чего это серверу не выбрать из 2х записей "0" в запросе SELECT TOP 1 ? сортировки то нет, захочет, и выберет.

Если бы оптимизатором был я, я бы вообще не выполнял часть с "from (values"; зачем, если возвращать всегда константу "0" будет по логике запроса безупречно правильно?
...
Рейтинг: 0 / 0
Сравнение со списком значений. Как будет правильно?
    #39849516
Фотография alexeyvg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
uaggsterНу или, может есть совсем правильное решение?А вообще, лучше такое хранить в словаре, а не в коде.
...
Рейтинг: 0 / 0
Сравнение со списком значений. Как будет правильно?
    #39849522
uaggster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
alexeyvg, Эээ... Union All выполняется последовательно, как except или intersect.
Т.е. к первому резалтсету всегда приклеивается второй и т.д.
Вот если б там union был, то точно б вернулся хаотически, т.к. он выполняется параллельно.
Вроде так.
Хотя, наверное, для полной уверенности можно добавить order by 1 desc.

А по поводу "в словаре" - это не моя компетенция. Почему разработчики не вынесли это в табличку - я не знаю.
Хотя по pattern всё равно ведь индекс не построишь. Построишь, но он всё равно сканироваться будет, не так ли?
...
Рейтинг: 0 / 0
Сравнение со списком значений. Как будет правильно?
    #39849534
Фотография alexeyvg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
uaggsterХотя, наверное, для полной уверенности можно добавить order by 1 desc.Ага, это гарантирует, а "к первому резалтсету всегда приклеивается второй и т.д." - только предположения.

uaggsterХотя по pattern всё равно ведь индекс не построишь. Построишь, но он всё равно сканироваться будет, не так ли?Я тут имел в виду администрирование всем этим хозяйством. Лучше словари хранить в справочниках, а не в коде, удобнее.
...
Рейтинг: 0 / 0
Сравнение со списком значений. Как будет правильно?
    #39849538
uaggster
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Да, alexeyvg, вы абсолютно правы.
Это не документированно, и лишь особенность оптимизатора:
https://sqlperformance.com/2017/05/sql-plan/union-all-optimization
Впрочем, в жизни б я все равно написал order by, просто потому, что испытывал бы чувство тревоги от потенциальной неоднозначности.
:)

Но это частности.
Почему с with то нельзя писать?
Мне заявляют - "я художник, я так вижу".
Как парировать то?
...
Рейтинг: 0 / 0
6 сообщений из 6, страница 1 из 1
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Сравнение со списком значений. Как будет правильно?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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