选择同名的所有行

时间:2016-07-07 05:42:52

标签: sql sql-server

我有像

这样的表格
$(".draggable i.remove-elem").off('click').on("click", function(){
        $(this).parent('.draggable').remove();
});

从这张表。我想得到表格

name  M1    m2   Tot
a      20   30    50
b      10   20    30    
a      20   10    30
a      30   15    45

怎么样那样?怎么写sql查询?或任何其他方式?

4 个答案:

答案 0 :(得分:0)

以下代码已经过测试并正常工作

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            DataTable dt1 = new DataTable();
            dt1.Columns.Add("name", typeof(string));
            dt1.Columns.Add("M1", typeof(int));
            dt1.Columns.Add("M2", typeof(int));
            dt1.Columns.Add("Tot", typeof(int));

            dt1.Rows.Add(new object[] {"a", 20, 30, 50});
            dt1.Rows.Add(new object[] {"b", 10, 20, 30});
            dt1.Rows.Add(new object[] {"a", 20, 10, 30});
            dt1.Rows.Add(new object[] {"a", 30, 15, 45});

            var groups = dt1.AsEnumerable()
                .GroupBy(x => x.Field<string>("name"))
                .ToList();

            int maxGroup = groups.Select(x => x.Count()).Max();

            DataTable dt2 = new DataTable();
            dt2.Columns.Add("name", typeof(string));
            for (int i = 1; i <= maxGroup; i++)
            {
                dt2.Columns.Add("Tot" + i.ToString());
            }
            foreach (var group in groups)
            {
                string name = group.Key;
                DataRow newRow = dt2.Rows.Add();
                newRow["name"] = name; 
                int numItems = group.Count();
                int[] totals = group.Select(x => x.Field<int>("Tot")).ToArray();
                for (int i = 1; i <= maxGroup; i++)
                {
                    if (i <= numItems)
                    {
                        newRow[i] = totals[i - 1];
                    }
                    else
                    {
                        newRow[i] = 0;
                    }
                }
            }

        }
    }
}

答案 1 :(得分:0)

这是经过测试并100%工作并产生您想要的结果(它也是动态的)并且不限于3总计

下面创建一个临时表,根据最大值创建动态数量的列 数字出现的特定列的值。然后动态填充这些列。基本上,您要为特定列值创建行的列。

您需要使用实际的表名更改T1的所有出现次数。

您可以创建一个存储过程:

DECLARE @MAXCOUNT INT = (SELECT MAX(R.c) FROM ( SELECT COUNT(*) c FROM T1 GROUP BY NAME) R)
DECLARE @NUMBER_OF_NAMES INT = (SELECT COUNT(*) FROM (SELECT DISTINCT NAME FROM T1) R)

PRINT @MAXCOUNT;
PRINT @NUMBER_OF_NAMES

SELECT DISTINCT NAME INTO #TEMP FROM T1

DECLARE @I INT = 0;
WHILE(@I < @MAXCOUNT)
BEGIN
    DECLARE @TOTINDEX INT = @I + 1;
    DECLARE @QUERY NVARCHAR(MAX) = 'ALTER TABLE #TEMP ADD TOT' 
                                + CONVERT(NVARCHAR(5), @TOTINDEX) + ' INT';
    EXEC (@QUERY);


    DECLARE @UPDATE NVARCHAR(MAX) = 'UPDATE T 
     SET TOT' + CONVERT(NVARCHAR(5), @TOTINDEX) + 
' = (SELECT TOP 1 TOTAL FROM ( SELECT * FROM T1 WHERE Name = T.Name ORDER BY NAME OFFSET ' 
     + CONVERT(NVARCHAR(5), @I) + ' ROWS FETCH NEXT 1 ROWS ONLY ) R ) FROM #TEMP T';

     PRINT @UPDATE

     SET @I = @I + 1;

     EXEC(@UPDATE);
END

SELECT * FROM #TEMP

DROP TABLE #TEMP

结果:

NAME    TOT1    TOT2    TOT3
a        50      30      45
b        30     NULL     NULL

答案 2 :(得分:0)

DECLARE @T TABLE (name VARCHAR(1), M1 INT,   m2 INT,  Tot INT)
DECLARE @MAXOBS INT
INSERT INTO @T VALUES
('a',      20,   30,    50),
('b',      10,   20,    30),   
('a',      20,   10,    30),
('a',      30,   15,    45)



 SELECT NAME,TOT1,TOT2,TOT3, TOT1+TOT2+TOT3 AS TOTAL
FROM
(
SELECT  NAME, 
        ISNULL([1],0) AS TOT1,
        ISNULL([2],0) AS TOT2,
        ISNULL([3],0) AS TOT3
FROM 
(
SELECT  ROW_NUMBER() OVER (PARTITION BY NAME ORDER BY NAME) RN,
        NAME,
        TOT
FROM    T
) S
PIVOT (MAX(TOT) FOR RN IN ([1],[2],[3])) AS PVT
) T

如果您认为每个名称将有超过3行,则需要动态sql。

答案 3 :(得分:-1)

这实际上增加了表格中的冗余并违反了1NF表格。一种解决方案是,您可以再增加一个表。

select total from table1, table2 where table1.name = table2.name;