我有像
这样的表格$(".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查询?或任何其他方式?
答案 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;