Лично я использую Bash, и на моем VPS я имею в ~/.aliases этот, и он работает отлично:
запрет псевдонима = "sudo ufw отклоняют от $"
Я использую функцию, определяемую пользователем для этой задачи. Udf создает строку с разделителями, в которой все элементы соответствуют параметрам, затем вы вызываете udf из своего оператора select, чтобы вытянуть список с разделителями для каждой записи в наборе записей.
CREATE FUNCTION dbo.ud_Concat(@actioncategory int, @contactid int)
RETURNS VARCHAR(8000)
AS
BEGIN
DECLARE @sOutput VARCHAR(8000)
SET @sOutput = ''
SELECT @sOutput = COALESCE(@sOutput, '') + action + ', '
FROM dbo.actionitemtable
WHERE actioncategory=@actioncategory AND contact=@contact
ORDER BY action
RETURN @sOutput
END
SELECT
name,
dbo.ud_Concat(category1, contactid) as contactList
FROM contact c
INNER JOIN actionitemtable a ON c.contactid = a.contactid
вам необходимо предоставить дополнительную информацию о структуре вашей таблицы и о том, как они соединяются друг с другом.
вот общий пример объединения нескольких строк в один столбец:
declare @table table (name varchar(30)
,ID int
,TaskID char(3)
,HoursAssigned int
)
insert into @table values ('John Smith' ,4592 ,'A01' ,40)
insert into @table values ('Matthew Jones',2863 ,'A01' ,20)
insert into @table values ('Jake Adams' ,1182 ,'A01' ,100)
insert into @table values ('Matthew Jones',2863 ,'A02' ,50)
insert into @table values ('Jake Adams' ,2863 ,'A02' ,10)
SELECT DISTINCT
t1.TaskID
,SUBSTRING(
replace(
replace(
(SELECT
t2.Name
FROM @Table AS t2
WHERE t1.TaskID=t2.TaskID
ORDER BY t2.Name
FOR XML PATH(''))
,'</NAME>','')
,'<NAME>',', ')
,3,2000) AS PeopleAssigned
FROM @table AS t1
ВЫХОД:
TaskID PeopleAssigned
------ --------------------------------------
A01 Jake Adams, John Smith, Matthew Jones
A02 Jake Adams, Matthew Jones
(2 row(s) affected)
Это довольно абстрактно и сложно. Моей первоначальной реакцией был «сводный запрос», но чем больше я смотрел на него (и на предыдущие ответы), тем больше я думал: вы можете передать этот запрос команде разработчиков? Вы возвращаете «базу», а они пишут и применяют процедурный код, который упрощает задачу такого рода. Конечно, вы можете втиснуть его в SQL, но это не делает его подходящим местом для работы.
Вероятно, вам придется создать собственную агрегатную функцию. У Microsoft есть статья в базе знаний с примером кода здесь .
В соответствии с вашим запросом попробуйте следующее:
SELECT [Name],
STUFF(
(
SELECT ' ,' + [Action]
FROM [AactionItemTable]
WHERE [ActionCategory] = category1
AND [Contact] = contactid
FOR XML PATH('')
), 1, 2, ''
) AS [AdditionalData]
FROM [Contact] C
INNER JOIN [ActionItemTable] A
ON C.[ContactId] = A.[ContactId]
Думаю, это простейший способ сделать то, что вы хотите.
РЕДАКТИРОВАТЬ: если в найденном подзапросе нет действий, результат [AdditionalData]
будет NULL
.
Если вы не против использования курсоров, вы можете написать для этого свою собственную функцию. Вот пример, который будет работать с образцом БД Adventureworks:
CREATE FUNCTION CommaFunctionSample
(
@SalesOrderID int
)
RETURNS varchar(max)
AS
BEGIN
DECLARE OrderDetailCursor CURSOR LOCAL FAST_FORWARD
FOR
SELECT SalesOrderDetailID
FROM Sales.SalesOrderDetail
WHERE SalesOrderID = @SalesOrderID
DECLARE @SalesOrderDetailID INT
OPEN OrderDetailCursor
FETCH NEXT FROM OrderDetailCursor INTO @SalesOrderDetailID
DECLARE @Buffer varchar(max)
WHILE @@FETCH_STATUS = 0
BEGIN
IF @Buffer IS NOT NULL SET @Buffer = @Buffer + ','
ELSE SET @Buffer = ''
SET @Buffer = @Buffer + CAST(@SalesOrderDetailID AS varchar(12))
FETCH NEXT FROM OrderDetailCursor INTO @SalesOrderDetailID
END
CLOSE OrderDetailCursor
DEALLOCATE OrderDetailCursor
RETURN @Buffer
END
Вот как такая функция будет отображаться в запросе выбора:
SELECT AccountNumber, dbo.CommaFunctionSample(SalesOrderID)
FROM Sales.SalesOrderHeader