简体   繁体   中英

Concatenate string value of one column depending on other column in sql table or c# DataTable

I have a Table/DataTable in SQL/C# having data like as below:

  Description   Name
    ABC           AB
    ABCD          AB
    ABCD          CD
    ABCDF         AB
    ABCD          BC
    ABCDF         BC

I am trying to get output as below (name should be concatenate for description):

  Description   Name
    ABC           AB
    ABCD          AB, BC and CD
    ABCDF         AB and BC

I have written name alphabetically in output, but that is not necessary. For example, Name for 2nd row either can be AB, CD and BC or BC, CD and AB . I just need all names in a string for a particular description.

How can i get desired output in SQL or C#? please help me out.

I got the solution in both C# and SQL, Is there any other way to get same output? Which approach (sql or c#) should i use, if performance matters?

C#:

static void Main(string[] args)
        {
            DataTable dt = new DataTable("MyTable");
            dt.Columns.Add(new DataColumn("Name"));
            dt.Columns.Add(new DataColumn("Description"));
            DataRow dr = dt.NewRow();
            dr["Name"] = "AB";
            dr["Description"] = "ABC";
            dt.Rows.Add(dr);
            DataRow dr1 = dt.NewRow();
            dr1["Name"] = "AB";
            dr1["Description"] = "ABCD";
            dt.Rows.Add(dr1);
            DataRow dr2 = dt.NewRow();
            dr2["Name"] = "CD";
            dr2["Description"] = "ABCD";
            dt.Rows.Add(dr2);
            DataRow dr3 = dt.NewRow();
            dr3["Name"] = "AB";
            dr3["Description"] = "ABCDF";
            dt.Rows.Add(dr3);
            DataRow dr4 = dt.NewRow();
            dr4["Name"] = "BC";
            dr4["Description"] = "ABCD";
            dt.Rows.Add(dr4);
            DataRow dr5 = dt.NewRow();
            dr5["Name"] = "BC";
            dr5["Description"] = "ABCDF";
            dt.Rows.Add(dr5);

            StringBuilder sb = new StringBuilder();

            var grouped = from table in dt.AsEnumerable()
                            group table by new { DescriptionCol = table["Description"] } into groupby
                            select new
                          {
                              Value = groupby.Key,
                              ColumnValues = groupby
                          };

            foreach (var key in grouped)
            {
                Console.WriteLine(key.Value.DescriptionCol);
                Console.WriteLine("---------------------------");
                int i = 1;
                foreach (var columnValue in key.ColumnValues)
                {
                    string comma = " , ";
                    string and = " and ";

                    if (i > 1 && i < key.ColumnValues.Count())
                    {
                        sb.Append(comma);
                    }
                    else if (i > 1 && i == key.ColumnValues.Count())
                    {
                        sb.Append(and);
                    }

                    sb.Append(columnValue["Name"].ToString());
                    i++;
                }
                Console.WriteLine(sb.ToString());
                sb.Clear();
                Console.WriteLine();
            }
            Console.ReadLine();
        }

SQL:

create table myTable
(
  Description  nvarchar(100),
  Name nvarchar(100)
)

insert into myTable values
('ABC','AB'),
('ABCD','AB'),
('ABCD','CD'),
('ABCD','BC'),
('ABCDF','BC'),
('ABCDF','AB')


create table myTable1
(
  Description  nvarchar(100),
  Name nvarchar(100)
)

insert into mytable1 (Description, Name)
SELECT Description, Name = STUFF((SELECT ', ' + Name 
    FROM myTable AS t2 WHERE t2.Description = t.Description
     ORDER BY Description
     FOR XML PATH('')), 1, 1, '')
FROM myTable AS t
GROUP BY Description
ORDER BY Description;

--select * from mytable1

select 
    Description, 
    ISNULL(
       REVERSE(STUFF(REVERSE(Name), CHARINDEX(',', REVERSE(Name), 0),1,'dna ')), 
    Name) Name
From mytable1

select Description, SUBSTRING(Name, 0, (len(Name) - charindex(',', reverse(Name)))) +
Replace(SUBSTRING(Name, (len(Name) - charindex(',', reverse(Name))), len(Name)), 
', ', ' and ') from mytable1

There are different approaches, if you want concatenate many rows into a single text string. The SQL answer depends on your database system. On Microsoft SQL Server you can use FOR XML PATH method. See the discussion here Concatenate many rows into a single text string? .

CREATE TABLE tb(aaa INT,bbb INT)
Go 
INSERT INTO tb
SELECT 1,2 UNION ALL
SELECT 1,3 UNION ALL
SELECT 1,4 UNION ALL
SELECT 2,2 UNION ALL
SELECT 2,5 



select 
aaa, 
[values]=stuff(replace(replace((select [bbb] 
                                from tb 
                                where aaa=t.aaa for xml AUTO),
                                '"/><tb bbb="',','),
                        '"/>',''),1,9,'')
from tb t
group by aaa 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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