Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Microsoft SQL Server [игнор отключен] [закрыт для гостей] / Сравнение со списком значений. Как будет правильно? / 6 сообщений из 6, страница 1 из 1
14.08.2019, 18:23
    #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
14.08.2019, 22:13
    #39849515
alexeyvg
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Сравнение со списком значений. Как будет правильно?
uaggsterЯ хотел уже переписать их так (по прежнему в скалярку, чтобы не ломать логику запросов, которые на них базируются)
Но призадумался, а будет ли от этого польза и удовольствие?
Т.е. будет ли оно меньше грузить диск, процессор, и вообще- работать быстрее?То есть переписать тело скалярки? ИМХО без разницы.

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

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

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

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

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


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