Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 Запись во временную таблицу  [new]
NickBell
Member

Откуда: Tbilisi
Сообщений: 2867
Во Временную таблицу #Personaldate в поле kodebi в одну строку собираюсь записать перечень анализов. Вроде бы раньше заработал, но сейчас что-то пустые значения записываются, не поняла, почему это происходит. Или я неправильно создаю строку или же не так записываю во временную таблицу.

Это кусок, где создается такая строка и потом обновляется временная таблица #Personaldate

;
WITH
	kodebi_all AS
	(
	SELECT		id_patient_history, 
				top_test_mini
	FROM		top_test TP
				RIGHT JOIN baza B
					ON TP.id_top_test = B.id_top_test
	) 
UPDATE	PSD
SET		kodebi = kodebi+', ' +top_test_mini
FROM	#Personaldate PSD
		INNER JOIN kodebi_all as K 
		ON PSD.id_patient_history = K.id_patient_history 



Ниже приведен полный текст для процедуры:

+
[src][SRC sql]CREATE Table #Personaldate 
		(
		momartvis_tarigi Date, 
		visitis_time Date,
		id_patient int,
		id_patient_history int,
		gvarsaxeli nvarchar(200),
		birthday Date,
		SumOffasi money,
		kodebi nvarchar(MAX),
		organization nvarchar(500),
		id_organization int  
		)

;
WITH
	patients_gamokvlevebis_fasebi AS
	(
	SELECT		id_patient_history, 
				Sum(fasi) SumOffasi
	FROM		baza
	GROUP BY	id_patient_history
	)
INSERT INTO #Personaldate 
		(
		id_patient,
		id_patient_history,
		id_organization,
		momartvis_tarigi, 
		visitis_time,
		gvarsaxeli,
		birthday,
		SumOffasi,
		organization
		)
SELECT	P.id_patient,
		PH.id_patient_history,
		PH.id_organization,
		momartvis_tarigi,
		visitis_time,		
		CONCAT(gvari, ' ', saxeli, ' ', mamis_saxeli) gvarsaxeli,
		birthday,
		SumOffasi,
		organization		
FROM	patients P
		RIGHT JOIN patients_history PH
			ON P.id_patient = PH.id_patient
		INNER JOIN patients_gamokvlevebis_fasebi PGF
			ON PH.id_patient_history = PGF.id_patient_history 
		LEFT JOIN organization O
			ON PH.id_organization = O.id_organization 
WHERE	PH.id_organization Is Not Null

;
WITH
	kodebi_all AS
	(
	SELECT		id_patient_history, 
				top_test_mini
	FROM		top_test TP
				RIGHT JOIN baza B
					ON TP.id_top_test = B.id_top_test
	) 
UPDATE	PSD
SET		kodebi = kodebi+', ' +top_test_mini
FROM	#Personaldate PSD
		INNER JOIN kodebi_all as K 
		ON PSD.id_patient_history = K.id_patient_history 

SELECT * FROM #Personaldate
[/SRC][/SRC]


И почему по этой команде
DROP Table #Personaldate 

не удаляется таблица?
25 апр 17, 17:08    [20433369]     Ответить | Цитировать Сообщить модератору
 Re: Запись во временную таблицу  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 7641
NickBell,

Пустые - врят ли, скорее NULL значения. Потому, что top_test_mini может принимать NULL. Используйте CONCAT() вместо +, если версия сервера позволяет или isnull().

Как Вы определили, что DROP Table #Personaldate не удаляет временную таблицу?
25 апр 17, 17:19    [20433394]     Ответить | Цитировать Сообщить модератору
 Re: Запись во временную таблицу  [new]
o-o
Guest
во временной таблице в kodebi изначально NULL,
т.к. туда ничего не записывается при первоначальном инсерте.
а при апдэйте с этим NULL складывается еще что-то через зпт (зачем, если там изначально NULL?)
и NULL с чем-то там в сумме дает NULL.
наверное, не хватает записи чего-то в kodebi при первой вставке INSERT INTO #Personaldate
25 апр 17, 17:33    [20433424]     Ответить | Цитировать Сообщить модератору
 Re: Запись во временную таблицу  [new]
NickBell
Member

Откуда: Tbilisi
Сообщений: 2867
Владислав Колосов,

Еще раз проверила DROP Table #Personaldate и на этот раз выполнил успешно. Странно даже, вроде бы говорил что запрещен доступ к удалению.

Что касается объединения строк, то CONCAT мне объединил только запятую и первый анализ, а на остальных даже и не обратил внимания, впрочем, наверное не так надо делать

SET kodebi = CONCAT(kodebi,', ',top_test_mini) 
25 апр 17, 17:44    [20433451]     Ответить | Цитировать Сообщить модератору
 Re: Запись во временную таблицу  [new]
NickBell
Member

Откуда: Tbilisi
Сообщений: 2867
Под пустым значением я имела ввиду NULL
25 апр 17, 17:44    [20433452]     Ответить | Цитировать Сообщить модератору
 Re: Запись во временную таблицу  [new]
NickBell
Member

Откуда: Tbilisi
Сообщений: 2867
Похоже надо было проверку на существование таблицы сделать и если она етсь, то только тогда удалить.
Но что-то ниже приведенный код не заработал

IF
	OBJECT_ID('tempdb..#Personaldate')
IS NOT NULL
	DROP Table #Personaldate 


И выдал ошибку:
Cannot drop the table '#Personaldate', because it does not exist or you do not have permission.
25 апр 17, 18:04    [20433491]     Ответить | Цитировать Сообщить модератору
 Re: Запись во временную таблицу  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6801
NickBell,
код рабочий у вас

 IF
	OBJECT_ID('tempdb..#Personaldate') IS NOT NULL
	DROP Table #Personaldate 

 CREATE TABLE #Personaldate  (ID INT)
25 апр 17, 18:08    [20433501]     Ответить | Цитировать Сообщить модератору
 Re: Запись во временную таблицу  [new]
NickBell
Member

Откуда: Tbilisi
Сообщений: 2867
TaPaK,

Спасибо за подсказку, добавила ID INT и больше не ругается.

Что касается объединения строк, наверное мне просто показалось раньше, что заработал.

Сейчас в интернете нашла один вариант, но он для MySql, а для SQL не подходит.

https://ru.stackoverflow.com/questions/286719/Объединить-несколько-полей-с-одинаковыми-значениями-только-с-помощью-mysql


select concat(distinct top_test_mini) as names, id_patient_history
    from kodebi_all
    group by id_patient_history
25 апр 17, 18:22    [20433530]     Ответить | Цитировать Сообщить модератору
 Re: Запись во временную таблицу  [new]
o-o
Guest
для сбора чего-то там в 1 поле используют for xml path:
Сложение символьных полей в запросе для SQL Server 2005
25 апр 17, 18:40    [20433556]     Ответить | Цитировать Сообщить модератору
 Re: Запись во временную таблицу  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 7641
Там не update надо а что-то вроде:
DECLARE @v varchar(max);

WITH kodebi_all AS
()
SELECT @v = concat(@v, ', ' ,top_test_mini)
FROM ... ;

SELECT @v = stuff(@v,1,2,'');
25 апр 17, 19:11    [20433648]     Ответить | Цитировать Сообщить модератору
 Re: Запись во временную таблицу  [new]
o-o
Guest
это не MySQL, CONCAT тут это не сбор значений колонки в строку,
это обычная замена "+" для строк.
a ей надо собрать *колонку* в 1 значение через зпт, а не разные поля одной строки
25 апр 17, 19:20    [20433660]     Ответить | Цитировать Сообщить модератору
 Re: Запись во временную таблицу  [new]
msLex
Member

Откуда:
Сообщений: 7979
o-o
для сбора чего-то там в 1 поле используют for xml path:
Сложение символьных полей в запросе для SQL Server 2005

у него есть один минус, нельзя задать порядок складывания

но парни из Редмонд а услышали наши проклятья молитвы и добавили полноценный STRING_AGG в 2017 (он же vNext)

STRING_AGG

docs.microsoft.com
STRING_AGG ( expression, separator [ <order_clause> ] )

<order_clause> ::=
WITHIN GROUP ( ORDER BY <order_by_expression_list> [ ASC | DESC ] )
25 апр 17, 19:36    [20433709]     Ответить | Цитировать Сообщить модератору
 Re: Запись во временную таблицу  [new]
NickBell
Member

Откуда: Tbilisi
Сообщений: 2867
Заменила, только после каждого слова запятые понаставил ... :)
Это кнечно же меня не устраивает.

STRING_AGG к сожалению не подошел, не та версия стоит у меня

;
WITH
	kodebi_all AS
	(
	SELECT		id_patient_history, 
			top_test_mini
	FROM		top_test TP
			RIGHT JOIN baza B
				ON TP.id_top_test = B.id_top_test
	) 
SELECT		id_patient_history,
		kodebi = replace((select cast(top_test_mini as nvarchar) as 'data()' from kodebi_all where id_patient_history = t.id_patient_history for xml path('')), ' ', ', ')
FROM		kodebi_all t
GROUP BY	id_patient_history
25 апр 17, 21:03    [20433892]     Ответить | Цитировать Сообщить модератору
 Re: Запись во временную таблицу  [new]
TaPaK
Member

Откуда: Kiev
Сообщений: 6801
msLex,

автор
STRING_AGG в 2017 (он же vNext)

советовать даже не rtm это кощунство
25 апр 17, 21:50    [20434028]     Ответить | Цитировать Сообщить модератору
 Re: Запись во временную таблицу  [new]
o-o
Guest
TaPaK,
он же не советует,
он приятно удивлен, что они все-таки это сделали.
и делится радостью с сообществом
25 апр 17, 22:14    [20434094]     Ответить | Цитировать Сообщить модератору
 Re: Запись во временную таблицу  [new]
NickBell
Member

Откуда: Tbilisi
Сообщений: 2867
В целом, обошлось без создания временной таблицы и использования Update.

В одном месте пришлось схитрить, чтобы дать понять, где находится конец записи для дальнейшего объединения строк.
CONCAT(top_test_mini, '|') minitest

Полный текст:
;
WITH
	kodebi_all AS
	(
	SELECT		id_patient_history, 
				CONCAT(top_test_mini, '|') minitest
	FROM		top_test TP
				RIGHT JOIN baza B
					ON TP.id_top_test = B.id_top_test
	), 
	kodebi_all_sruli AS
	(
	SELECT		id_patient_history,
				KDO = replace((select cast(minitest as nvarchar) as 'data()' from kodebi_all where id_patient_history = t.id_patient_history for xml path('')), '|', (', '))
	FROM		kodebi_all t
	GROUP BY	id_patient_history
	),
	patients_gamokvlevebis_fasebi AS
	(
	SELECT		id_patient_history, 
				Sum(fasi) SumOffasi
	FROM		baza
	GROUP BY	id_patient_history
	)
SELECT	P.id_patient,
		PH.id_patient_history,
		PH.id_organization,
		momartvis_tarigi,
		visitis_time,		
		CONCAT(gvari, ' ', saxeli, ' ', mamis_saxeli) gvarsaxeli,
		birthday,
		KDO,
		SumOffasi,
		organization		
FROM	patients P
		RIGHT JOIN patients_history PH
			ON P.id_patient = PH.id_patient
		INNER JOIN patients_gamokvlevebis_fasebi PGF
			ON PH.id_patient_history = PGF.id_patient_history 
		LEFT JOIN organization O
			ON PH.id_organization = O.id_organization 
		INNER JOIN kodebi_all_sruli as K 
			ON PH.id_patient_history = K.id_patient_history 

Всем огромное спасибо за помощь.
26 апр 17, 09:21    [20434589]     Ответить | Цитировать Сообщить модератору
 Re: Запись во временную таблицу  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 7641
NickBell,

какие-то главари и стаксели :D У вас там морская пиратская база?
CONCAT(gvari, ' ', saxeli, ' ', mamis_saxeli) - такое, вообще-то, собирают на клиенте, а сервер не утруждают.
26 апр 17, 10:39    [20434900]     Ответить | Цитировать Сообщить модератору
 Re: Запись во временную таблицу  [new]
NickBell
Member

Откуда: Tbilisi
Сообщений: 2867
Владислав Колосов,

Не понимаю о чем речь. Разве на стороне клиента не будет жалоб как всё медленно работает?
Я делаю SQL в связке с Access и, в данном случае, в Access вызываю готовый запрос.
Разве не так делается по идее? Зачем мне часть в другом месте делать и часть в другом?
26 апр 17, 11:01    [20435008]     Ответить | Цитировать Сообщить модератору
 Re: Запись во временную таблицу  [new]
NickBell
Member

Откуда: Tbilisi
Сообщений: 2867
Владислав Колосов
NickBell,

какие-то главари и стаксели :D У вас там морская пиратская база?
CONCAT(gvari, ' ', saxeli, ' ', mamis_saxeli)


морская пиратская база?

Похоже так звучит для некоторых ...
Да, так и есть для некоторых, хотя это просто фамилия, имя и отчество
26 апр 17, 11:27    [20435092]     Ответить | Цитировать Сообщить модератору
 Re: Запись во временную таблицу  [new]
Владислав Колосов
Member

Откуда:
Сообщений: 7641
NickBell,

вопрос тонкий, обычно сервер стараются не нагружать обработкой строк, т.е. ему и без того есть чем заняться. :) Так бы вы получили на выходе чистый список столбцов без дополнительных вычислений на стороне сервера, а клиент бы потратил свое процессорное время на преобразование данных.
26 апр 17, 14:21    [20436112]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить