| 
							DM
							 
								Гость 
							 
						 | 
						
							
								  | 
								
									
									 «  : 27-09-2004 14:01 »   | 
								
								 | 
							  
							 
							Проблема в том что функция SUM работает только с числовыми типами данных   , а мне надо в селекте выбрать сумму строк (простая конкатенация). Select - обычный запрос c GROUP BY. Если бы был числовой тип, то SUM дала бы арифметическую сумму, а мне то надо "сложить" строки ...  Может можно свою БД-функцию сделать? Но надо чтобы она работала в самых разных селектах с разными таблицами и WHERE условиями. Общее у селектов - только GROUP BY и тип колонки - строковый.  Может решения нет и надо каждый раз организовывать цикл, внутри которого клеить строки? Не хотелось бы   ( P.S.  БД - Microsoft SQL Server  
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						
							Dimka
							
								Деятель 
								Команда клуба
								
								 
								  Offline
								Пол:   
								
								
								
								
								
							 
						 | 
						
							
								  | 
								
									
									 « Ответ #1 : 27-09-2004 17:41 »   | 
								
								 | 
							  
							 
							DM, задача не совсем понятна. Есть тип данных varchar или nvarchar. Их размеры ограничены 8К и 4К символами. Конкатенация строк в групповом операторе SUM, чтобы быть универсальной, должна предполагать размер результата типа text (2 Гб), а для типа text вообще не применяться. Естественно, такой операции нет и в обозримом будущем не будет - слишком узок класс задач и ограничен объём данных (число записей), для которых такая операция в рамках указанных ограничений была бы полезна.
  Кстати, опиши задачу, возможно, ты её не так решаешь или создал неудобную структуру данных - может подкину идеи других решений. 
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
							 
							Программировать - значит понимать (К. Нюгард) Невывернутое лучше, чем вправленное (М. Аврелий) Многие готовы скорее умереть, чем подумать (Б. Рассел) 
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						| 
							DM
							 
								Гость 
							 
						 | 
						
							
								  | 
								
									
									 « Ответ #2 : 28-09-2004 08:06 »   | 
								
								 | 
							  
							 
							dimka, тип данных - nvarchar. Причем строки короткие и их немного, результат конкатенации априори не будет больше 4000 символов. Структуру данных создал не я и менять ее не могу    . Другие решения, конечно, есть,  но все они менее удобные. Я надеялся на какую нибудь идейку в плане хранимых  процедур, но, наверное, это нереализуемо. Задачу описывать неинтересно, если решения на данный вопрос нет, ее действительно придется делать совсем подругому.  
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						
							Dimka
							
								Деятель 
								Команда клуба
								
								 
								  Offline
								Пол:   
								
								
								
								
								
							 
						 | 
						
							
								  | 
								
									
									 « Ответ #3 : 28-09-2004 08:32 »   | 
								
								 | 
							  
							 
							DM, не, ну хранимую процедуру написать можно, но это будет тот самый цикл, который тебе не нравится.
  Курсором бежишь по записям и складываешь. И будет на стороне сервера, а не на клиенте.
  Я просто объяснил, почему такой функции нет и пока что не будет. 
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
							 
							Программировать - значит понимать (К. Нюгард) Невывернутое лучше, чем вправленное (М. Аврелий) Многие готовы скорее умереть, чем подумать (Б. Рассел) 
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						| 
							DM
							 
								Гость 
							 
						 | 
						
							
								  | 
								
									
									 « Ответ #4 : 28-09-2004 09:18 »   | 
								
								 | 
							  
							 
							А можно ли вызывать хранимую процедуру из селекта? Мне надо чтоб был select обязательно, это ограничение такое дурацкое, но непреодолимое     .  
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						| 
							DM
							 
								Гость 
							 
						 | 
						
							
								  | 
								
									
									 « Ответ #5 : 28-09-2004 09:59 »   | 
								
								 | 
							  
							 
							  Вроде как user-defined function можно вызывать из селекта, а в саму функцию передать те же самые FROM и WHERE, которые будут в самом селекте. Попробую ...  
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						
							Dimka
							
								Деятель 
								Команда клуба
								
								 
								  Offline
								Пол:   
								
								
								
								
								
							 
						 | 
						
							
								  | 
								
									
									 « Ответ #6 : 28-09-2004 14:38 »   | 
								
								 | 
							  
							 
							Из select хранимую процедуру не вызовешь, так как в общем случае заранее неизвестен результат процедуры (таблица, множество таблиц или скалярное значение) - черевато ошибками в runtime, можно лишь insert exec сделать - специально для возможности обработки результатов хранимых процедур через временные таблицы.
  Ещё раз прошу, опиши задачу - возможно, есть другое решение и одним запросом или процедурой. Мне просто интересно, какая такая задача может потребовать сложения строк в select, да ещё не простое, а с какими-то условиями. 
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
							 
							Программировать - значит понимать (К. Нюгард) Невывернутое лучше, чем вправленное (М. Аврелий) Многие готовы скорее умереть, чем подумать (Б. Рассел) 
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						| 
							Sla
							
						 | 
						
							
								  | 
								
									
									 « Ответ #7 : 28-09-2004 15:05 »   | 
								
								 | 
							  
							 
							Пример могу сказать получить текст сообщения , которое заранее отформатированное по полям или по к-л правилу например ID Field1 Val   10 адрес     хххххх ID Field2 Val   10 город    ннннннн ID Field3 Val   10 лицо    сссссссссс и все это в одной таблице 
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
							 
							Мы все учились понемногу... Чему-нибудь и как-нибудь. 
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						| 
							Anonymous
							 
								Гость 
							 
						 | 
						
							
								  | 
								
									
									 « Ответ #8 : 28-09-2004 15:44 »   | 
								
								 | 
							  
							 
							Удалось все оформить в виде user-defined function, и вроде заработало, правда пока в  несколько упрощенном виде. Описать задачу ... Да... непросто, но попробую раз интересно.  Есть некая оболочка (доморощенная, но не мной писаная).  Она строит объекты по некоторым описаниям, в том числе должен быть указан источник данных -  select. В результате может быть создан, например реестр деталей. Этот реестр отображается в гриде на форме. Туда же можно пихнуть кнопки каких-то операций, а к нопкам привязать методы. Все это делается из этой оболочки, код на языке никакой не пишется. Для особо нестандартных случаев можно и свой код в Visual Studio написать и присандалить. Ну вот и потребовалось сделать несколько десятков объектов, для которых  несколько экранных  строк соответсвуют большему числу реальных строк. В селекте это достигается элементарной группировкой. Сам селект указывается в виде источника данных в этой оболочке. Проблема начинается дальше - экранные строки надо раскрывать, т.е. высветить, например, все реальные строки из БД для одной какой-то строки экрана. Или пользователь отметит 3 строчки и захочет удалить их. Для этого легко и просто подключить свой код на C#.  Но что получит в распоряжение код? - правильно, только то, что было выбрано в данном селекте. А селект только один и указывается в оболочке и никак иначе. Вот и возникла идея склеить все ключи для каждой строки SELECT GROUP BY в одну строчку, а ее то и передать в свой блок кода. Эту строчку можно разобрать и выделить все содержащиеся в ней ключи , однозначно идентифицировав все нужные строчки датабазной таблицы.  В этом  то и цель. Тут еще важно, что новых строк принципиально заводится не может, только просмотр и удаление. А объектов таких много, у каждого свои WHERE и разные колоноки группировки и число оных разное, в общем  не хочется селекты дублировать. Пусть сидят только в одном месте - в источнике данных, а он в яйце, то биш в оболочке. 
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						| 
							DM
							 
								Гость 
							 
						 | 
						
							
								  | 
								
									
									 « Ответ #9 : 28-09-2004 15:59 »   | 
								
								 | 
							  
							 
							Гость это я, забыл зарегистрироваться.  Sla, мне не форматировать надо строки , а просто склеить.  Как это делает функция SUM для чисел: SELECT group_id, SUM(netto_weight) FROM table_name GROUP BY group_id Только вместо float - nvarchar, а вместо операции суммирования- конкатенация строк. Но спасибо всем, проблема  решилась.    
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						
							Dimka
							
								Деятель 
								Команда клуба
								
								 
								  Offline
								Пол:   
								
								
								
								
								
							 
						 | 
						
							
								  | 
								
									
									 « Ответ #10 : 29-09-2004 11:09 »   | 
								
								 | 
							  
							 
							Как происходит "высвечиваение строк" из таблицы, соответствующих одной экранной строке? - проблема решается дополнительным select'ом, когда ты разворачиваешь группу по известному общему для них идентификатору экранной строки (groupid в данном случае) или какому угодно - в любом случае он есть! Зачем извлекать все данные из базы сразу? Если появилась потребность, значит ты эту свою оболочку расширил функцией раскрытия группы - вот тутда и вставь дополнительный select. 
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
							 
							Программировать - значит понимать (К. Нюгард) Невывернутое лучше, чем вправленное (М. Аврелий) Многие готовы скорее умереть, чем подумать (Б. Рассел) 
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						| 
							DM
							 
								Гость 
							 
						 | 
						
							
								  | 
								
									
									 « Ответ #11 : 29-09-2004 12:49 »   | 
								
								 | 
							  
							 
							dimka, кому известен это groupid    Он же указывается в запросе, а запрос указывается в оболочке. Программа может получить доступ к полям, которые выберуться в результате работы запроса. И все. Поэтому и важно, чтобы в одном из полей результата селекта сидело что-то, что однозначно идентифицирует группу.  Но дискуссия стала слишком частной, давай здесь ее закроем. Если очень хочется, побеседуем лично     .  
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						
							Dimka
							
								Деятель 
								Команда клуба
								
								 
								  Offline
								Пол:   
								
								
								
								
								
							 
						 | 
						
							
								  | 
								
									
									 « Ответ #12 : 29-09-2004 15:06 »   | 
								
								 | 
							  
							 
							ничего не частной - всё равно в этой теме продолжения не будет, поэтому можно и здесь   Т.е. ты имеешь в распоряжении своём только выборку для основной экранной таблицы и всё... И из этих данных (причём в общем случае) надо суметь развернуть группу... Вот теперь задача сформулирована, и её можно попробовать решать   . Пойду подумаю   .  
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
							 
							Программировать - значит понимать (К. Нюгард) Невывернутое лучше, чем вправленное (М. Аврелий) Многие готовы скорее умереть, чем подумать (Б. Рассел) 
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						| 
							Anonymous
							 
								Гость 
							 
						 | 
						
							
								  | 
								
									
									 « Ответ #13 : 30-09-2004 06:46 »   | 
								
								 | 
							  
							 
							dimka, спасибо за участие     . Но поместить идентификатор группы в результат селекта можно только 2-мя способами: 1) Включить все атрибуты GROUP BY в select и пометить их как-то, например задав специальные имена. Это можно сделать без особых хитростей, но для меня это неудобно (группы очень разнообразны). 2) Каким-то образом склеить все ключи для группы в строку через разделитель, например, пробел. Благо ключ всегда целчисленный ID c фиксированным именем. Это, конечно, грязный вариант, просто в данном конкретном случае для меня он удобен. Тут была бы идеальна функция SUM для строк. Жаль, что ее нет    . Если надумаешь что-то кардинально иное - :l_wink:  
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						| 
							DM
							 
								Гость 
							 
						 | 
						
							
								  | 
								
									
									 « Ответ #14 : 30-09-2004 06:54 »   | 
								
								 | 
							  
							 
							А сделал я так - загнал селекты в функцию, возвращающую таблицу. В функции в цикле клею ключи в строку. Все работает как хотелось. Так что, dimka, интерес остался чисто спортивный. 
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						
							Dimka
							
								Деятель 
								Команда клуба
								
								 
								  Offline
								Пол:   
								
								
								
								
								
							 
						 | 
						
							
								  | 
								
									
									 « Ответ #15 : 04-10-2004 14:23 »   | 
								
								 | 
							  
							 
							В общем случае задача развёртывания группы не решается - восстановить нельзя. Но ты вводишь дополнительное поле, где хранишь идентификаторы - значит имеешь доступ к исходным запросам. Можно в виде строки в дополнительном поле хранить запрос на раскрытие группы. В общем, плохая архитектура, но такова участь программиста на этапе сопровождения    
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
							 
							Программировать - значит понимать (К. Нюгард) Невывернутое лучше, чем вправленное (М. Аврелий) Многие готовы скорее умереть, чем подумать (Б. Рассел) 
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						| 
							DM
							 
								Гость 
							 
						 | 
						
							
								  | 
								
									
									 « Ответ #16 : 06-10-2004 09:46 »   | 
								
								 | 
							  
							 
							dimka, а как этот запрос на раскрытие группы загнать в результат селекта? Результат селекта - несколько строк, и для каждой строки конкретные значения полей, идентифицирующие группу - свои. И значения эти - собственно результат селекта. Поэтому такой запрос по сути своей будет просто перечислением параметров. А значения параметров - это значения полей, результат исходного селекта. В общем-то это я и предлагал в качестве альтернативного варианта раньше.  Или ты что-то иное имеешь ввиду     ?  
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						
							Dimka
							
								Деятель 
								Команда клуба
								
								 
								  Offline
								Пол:   
								
								
								
								
								
							 
						 | 
						
							
								  | 
								
									
									 « Ответ #17 : 06-10-2004 10:04 »   | 
								
								 | 
							  
							 
							допустим, простейший случай запроса главной таблицы: select sum(total), year from table group by year отсюда следует, что раскрытие конкретной группы будет выглядеть так: select  total, year from table where year = @year где @year - параметр, извлекаемый из той конкретной строчки, в которую тыкнулся юзер в таком случае окончательно запрос главной таблицы будет выглядеть так  select   sum)t.total: as sum,    t.year,    'select  t.total, t.year from table t where t.year = ' + convert)varchar, t.year: as grqry from table t group by t.year
 
 здесь ты сразу раскрываешь параметр, т.е. остаётся исполнить запрос из поля grqry без каких-либо дополнительных преобразований. как выше сказано, если у тебя несколько параметров группировки, то они разворачиваются так исходное group by year, month разворот группы where year = @year and month = @month вот что я имел ввиду    
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
							 
							Программировать - значит понимать (К. Нюгард) Невывернутое лучше, чем вправленное (М. Аврелий) Многие готовы скорее умереть, чем подумать (Б. Рассел) 
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						| 
							DM
							 
								Гость 
							 
						 | 
						
							
								  | 
								
									
									 « Ответ #18 : 06-10-2004 13:32 »   | 
								
								 | 
							  
							 
							Действительно, сразу сформировать строку WHERE прямо в селекте - свежая мысль  :idea: .  Уже вижу, где мне это пригодится, спасибо  :l_wink: 
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						
							Dimka
							
								Деятель 
								Команда клуба
								
								 
								  Offline
								Пол:   
								
								
								
								
								
							 
						 | 
						
							
								  | 
								
									
									 « Ответ #19 : 06-06-2005 16:08 »   | 
								
								 | 
							  
							 
							Увидел-таки решение первой задачи, сформулированной в этой теме, для SQLServer, без курсора и не для использования в GROUP BY, хотя можно через UDF реализовать и в запросах с GROUP BY. DECLARE @T nvarchar(4000) SET @T = ''
  SELECT @T = @T + (CASE WHEN LEN(@T) > 0 THEN ', ' ELSE '' END) + xtype FROM sysobjects
  PRINT @T
   
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
									« Последнее редактирование: 20-12-2007 20:41 от Алексей1153++ »
								 | 
								
									 
									Записан
								 | 
							  
							 
							Программировать - значит понимать (К. Нюгард) Невывернутое лучше, чем вправленное (М. Аврелий) Многие готовы скорее умереть, чем подумать (Б. Рассел) 
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						| 
							sagarkov
							 
								Гость 
							 
						 | 
						
							
								  | 
								
									
									 « Ответ #20 : 12-11-2009 08:40 »   | 
								
								 | 
							  
							 
							А можно сделать так же в MySQL 5.1? 
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						| 
							Sla
							
						 | 
						
							
								  | 
								
									
									 « Ответ #21 : 12-11-2009 08:44 »   | 
								
								 | 
							  
							 
							sagarkov, что реализовать?
  зы. Тема довольно старая, поэтому  - опиши задачу.
  
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
							 
							Мы все учились понемногу... Чему-нибудь и как-нибудь. 
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						| 
							sagarkov
							 
								Гость 
							 
						 | 
						
							
								  | 
								
									
									 « Ответ #22 : 12-11-2009 09:02 »   | 
								
								 | 
							  
							 
							Мне нужно конкатенировать строки внутри группы после операции group by. Пишу что-то вроде: SET @path:=''; SELECT @path := concat_ws('|', @path, subject) as path2, count(*), phone from MessageLog group by phone; но не работает. 
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						| 
							RXL
							
						 | 
						
							
								  | 
								
									
									 « Ответ #23 : 12-11-2009 14:58 »   | 
								
								 | 
							  
							 
							В MySQL есть групповая функция для конткатенации - GROUP_CONCAT(). SELECT GROUP_CONCAT(CONCAT(a, ' ', b, ' ', c) ORDER BY a SEPARATOR ';') FROM tab;  
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
							 
							... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С. 
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						
							Алексей++
							
								глобальный и пушистый 
								Глобальный модератор
								
								 
								  Offline
								
								Сообщений: 13
								
								
								
								
								
							  
						 | 
						
							
								  | 
								
									
									 « Ответ #24 : 12-11-2009 15:06 »   | 
								
								 | 
							  
							 
							а что значит SEPARATOR ';' 
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
							 
							
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						| 
							RXL
							
						 | 
						
							
								  | 
								
									
									 « Ответ #25 : 13-11-2009 04:53 »   | 
								
								 | 
							  
							 
							Леш, а по смыслу что это значит?    По словарю: "SEPARATOR" - "разделитель". Значит разделяет он объединяемые элементы.  
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
							 
							... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С. 
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						
							Алексей++
							
								глобальный и пушистый 
								Глобальный модератор
								
								 
								  Offline
								
								Сообщений: 13
								
								
								
								
								
							  
						 | 
						
							
								  | 
								
									
									 « Ответ #26 : 13-11-2009 05:07 »   | 
								
								 | 
							  
							 
							ну значение слова то я знаю
  то есть должно получиться
  a; ;b; ;c
  а я полагал, автору надо a b c
  
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
							 
							
						 | 
					 
				 
			 |  
		 
	 | 
	
		
		
			
				
					
						| 
							RXL
							
						 | 
						
							
								  | 
								
									
									«  Ответ #27 : 13-11-2009 06:09 »    | 
								
								 | 
							  
							 
							Дык, я только пример дал - дальше уж делай что хошь...
  И, кстати, ты неверно интерпретировал. Будет: a1 b1 c1;a2 b2 c2;a3 b3 c3... 
						 | 
					 
					
						
							
								| 
								 | 
							 
								| 
								 | 
								
									 
									Записан
								 | 
							  
							 
							... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С. 
						 | 
					 
				 
			 |  
		 
	 | 
	 |