简体   繁体   English

如何在SQL Server中将数据收集到单行

[英]How to collect data to single row in sql server

I have table Risks and history table Risks_history . 我有风险表和历史记录表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: 我需要在历史记录中保存表Risks的数据,如下所示:

-------------------------------------
| 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: 但是在Risks_history表中,我有如下数据(触发器写到):

 - 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 但是无论风险如何变化,我都需要写所有风险

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

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

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, 修改后的触发器并假设DealID和Description是Risks表的列名称,

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
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

You can get this output with one single SQL query like this: 您可以通过单个SQL查询获得此输出,如下所示:

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. 现在,您必须将此查询放在触发器下才能将过滤器数据插入表中。

在此处输入图片说明

We can use MIN in the ID and DealID in GROUP BY: 我们可以在ID中使用MIN,在GROUP BY中使用DealID:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM