问题
I have table Risks and history table Risks_history. In Risks table i have data like below:
-----------------------------
| ID | DealID | Description |
-----------------------------
| 1 | 14 | Risk1 |
-----------------------------
| 2 | 14 | Risk2 |
-----------------------------
| 3 | 14 | Risk3 |
-----------------------------
| 4 | 15 | Risk4 |
-----------------------------
So here is we can see that one deal can have several Risks. I need to save data of table Risks in history like below:
-------------------------------------
| ID | dealID | AllDescriptions |
-------------------------------------
| 1 | 14 | Risk1, Risk2, Risk3 |
-------------------------------------
| 2 | 15 | Risk4 |
-------------------------------------
I need trigger that will do it. But now I cant.
How I can collect data from several rows into one row?
EDIT:
I need trigger, so now i have below trigger:
INSERT INTO [dbo].[Risks_history]
(
DealID,
[AllDescription]
)
SELECT
[DealID],
stuff((select ',' + i.name from inserted i
where i.DealID= i2.DealID
FOR XML PATH('')),1,1,'') as Description
FROM inserted i2;
But in table Risks_history i have data(which trigger wrote) like below:
- When I change Risk1:
-------------------------------------
| ID | dealID | AllDescriptions |
-------------------------------------
| 1 | 14 | Risk1, Risk1, Risk1 |
-------------------------------------
- When I change Risk2:
-------------------------------------
| ID | dealID | AllDescriptions |
-------------------------------------
| 1 | 14 | Risk2, Risk2, Risk2 |
-------------------------------------
- When I change Risk3:
-------------------------------------
| ID | dealID | AllDescriptions |
-------------------------------------
| 1 | 14 | Risk3, Risk3, Risk3 |
-------------------------------------
But I need to write all Risks whatever risk changing
回答1:
Please try this..
SELECT DISTINCT
DealID
, STUFF((
SELECT N', ' + CAST([Description] AS VARCHAR(4000))
FROM Risks R2
WHERE R1.DealID = R2.DealID
FOR XML PATH (''), TYPE), 1, 2, '') AS AllDescriptions
FROM Risks R1
GROUP BY DealID
Your modified trigger and assuming DealID and Description are column names of Risks tables,
DECLARE @DealID INT;
SELECT
@DealID = [DealID]
FROM inserted;
INSERT INTO [dbo].[Risks_history]
(
DealID,
[AllDescription]
)
SELECT
[DealID],
STUFF((
SELECT ', ' + R2.[Description]
FROM Risks R2
WHERE R1.DealID = R2.DealID
FOR XML PATH (''), TYPE), 1, 2, '') AS AllDescriptions
FROM Risks R1
WHERE DealID = @DealID
GROUP BY DealID
回答2:
Try this,
SELECT
ID,
STUFF((
SELECT ', ' + CAST(Description AS VARCHAR(MAX))
FROM Risks
WHERE (ID = RiskMain.ID)
FOR XML PATH (''), TYPE), 1, 2, '') AS AllDescriptions
FROM Risks RiskMain
GROUP BY ID
回答3:
create table #c
( ID int, DealID int, Description varchar(10))
insert into #c values
(1,14,'Risk1'),
(2,14,'Risk2'),
(3,14,'Risk3'),
(4,15,'Risk4')
SELECT DISTINCT DealID,
STUFF((SELECT ','+Description
FROM #c t1
WHERE t1.DealID = t2.DealID
FOR XML PATH(''))
,1,1,'') as Description
FROM #c t2
回答4:
DECLARE @tblTest AS TABLE
(
ID INT,
DealID INT,
Description VARCHAR(50)
)
INSERT INTO @tblTest VALUES(1,14,'Risk1')
,(2,14,'Risk2')
,(3,14,'Risk3')
,(4,15,'Risk4')
SELECT STUFF((SELECT distinct ',' + QUOTENAME(Description)
FROM @tblTest c
--WHERE c.DealID=T.DealID
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
SELECT
ROW_NUMBER() OVER (ORDER BY MAX(T.ID)) AS ID,
T.DealID,
(SELECT STUFF((SELECT distinct ',' + Description
FROM @tblTest c
WHERE c.DealID=T.DealID
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')) AS AllDescriptions
FROM @tblTest T
GROUP BY T.DealID
回答5:
You can get this output with one single SQL query like this:
SELECT t1.DealID,
Descriptions =REPLACE( (SELECT Description AS [data()]
FROM Risks_history t2
WHERE t2.DealID = t1.DealID
ORDER BY Description
FOR XML PATH('')
), ' ', ',')
FROM Risks_history t1
GROUP BY DealID ;
Now you have to put this query under the trigger to insert filter data into your table.
回答6:
We can use MIN in the ID and DealID in GROUP BY:
SELECT MIN(u.ID) AS ID,
u.DealID,
STUFF((SELECT ', ' + A.Description FROM Mytable A
WHERE A.DealID=u.DealID FOR XML PATH('')),1,1,'') As [Description]
FROM Mytable u
GROUP BY u.DealID
来源:https://stackoverflow.com/questions/40152481/how-to-collect-data-to-single-row-in-sql-server