根据值合并和显示表数据

时间:2016-06-20 16:21:23

标签: c# sql asp.net

我正在尝试创建一个显示行的表,但是如果有一个显示相同的model_number和year_introduced,那么合并它们但是将第二行的位置添加到第一行

所以我现在有一张看起来像这样的表

archive_id    model_number    year_introduced    location
1001          B12             2012               SKID 43
1002          B12             2012               SKID 47
1003          B12             2012               SKID 41
1004          B12             2012               SKID 56

但我希望它看起来像这样

archive_id    model_number    year_introduced    location
1001          B12             2012               SKID 43, SKID 47, SKID 41, SKID 56

我正在使用C#和ASP.NET显示数据,所以我会调整查询以合并行,或者我会使用C#将它们合并到我拥有的DataTable中

这是我如何显示数据(它不包括所有数据,因为更多信息按钮会将它们带到包含所有数据的页面)

foreach (DataRow dataRow in ds.Tables[0].Rows)
{
    yearHead.InnerText = decade.ToString() + "'s";
    TableRow row = new TableRow();
    row.ID = "rows" + x;
    row.Attributes.Add("class", "tblRow");

    TableCell cell = new TableCell();
    cell.Attributes.Add("class", "cell");
    cell.ID = "product_name" + x;
    cell.Text = dataRow["PRODUCT_NAME"].ToString();
    row.Cells.Add(cell);

    cell = new TableCell();
    cell.ID = "model_number" + x;
    cell.Text = dataRow["MODEL_NUMBER"].ToString();
    row.Cells.Add(cell);

    cell = new TableCell();
    cell.ID = "years" + x;
    if (dataRow["YEAR_INTRODUCED"] != null)
    {
        cell.Text = dataRow["YEAR_INTRODUCED"].ToString();
        row.Cells.Add(cell);
    }
    else
    {
        cell.Text = "Unknown Start Date";
        row.Cells.Add(cell);
    }

    cell = new TableCell();
    cell.ID = "more_info" + x;

    Button moreInfo = new Button();
    moreInfo.Attributes.Add("runat", "server");
    moreInfo.UseSubmitBehavior = false;
    moreInfo.CommandName = "moreInfoClicked";
    moreInfo.Text = "Details";
    moreInfo.ID = "info_" + dataRow["ARCHIVE_ID_NUMBER"].ToString();
    moreInfo.CommandName = x.ToString();
    moreInfo.CommandArgument = dataRow["ARCHIVE_ID_NUMBER"].ToString();
    moreInfo.ControlStyle.CssClass = "moreInfoButton";

    cell.Controls.Add(moreInfo);
    row.Cells.Add(cell);

    product.Rows.Add(row);
    x += 1;
}

4 个答案:

答案 0 :(得分:0)

最简单的方法是在SQL Server端转换列值int列表,然后将生成的rowset(datatable)绑定到GridViewListView

select distinct model_number, year_introduced
,stuff((select ', '+location as [text()]  
       from tbl t1 
          where t1.year_introduced = t.year_introduced 
            and t1.model_number = t.model_number for xml  path('')),1,1,'') lst
from tbl t

请注意,此处不能包含archive_id,因为每个值都会产生不同的location。您可以将类似技巧应用于archive_id列,或将archive_idlocation结合使用。

select ', ' + cast(archive_id as varchar) + ': ' + location as [text()]...

答案 1 :(得分:0)

这将具有您在问题中指定的archieve_id,并且数据将在位置列中以逗号组合

SELECT  min([archive_id]) as archive_id,[model_number],[year_introduced],
     STUFF((
             SELECT ', '  + CAST([location] AS VARCHAR(MAX)) 
                   FROM 
             [Test]
                   WHERE 
             ([model_number] = Results.[model_number] and [year_introduced]=                                                             Results.[year_introduced]) 
             FOR XML PATH(''),TYPE).value('(./text())[1]','VARCHAR(MAX)')
             ,1,2,'') AS Location
                   FROM 
             [Test] Results
                    GROUP BY 
             [model_number],[year_introduced]

答案 2 :(得分:0)

如果您使用的是SQL Server 2017,则可以执行以下操作:

SELECT model_number, year_introduced, 
STRING_AGG (location , ',') WITHIN GROUP (ORDER BY archive_id) AS locations 
FROM Yourtable
GROUP BY model_number, year_introduced

否则,请使用

SELECT t0.model_number, t0.year_introduced
     , STUFF((
       SELECT ',' + t1.location
         FROM yourtable t1
        WHERE t0.model_number=t1.model_number and t0.year_introduced=t1.year_introduced
        ORDER BY t1.archive_id
          FOR XML PATH('')), 1, LEN(','), '') AS Locations
  FROM yourtable t0
 GROUP BY t0.model_number, t0.year_introduced

答案 3 :(得分:-1)

在我看来,使用C#合并结果是最有效的。