首页 > 解决方案 > 如何根据特定参数对计数的 DataTable 行进行排序

问题描述

我正在尝试使用dataTable.Rows.Count,但根据特定参数对结果进行排序。该参数在我的DataTable. 所以输出只给了我与那个不同的值有关的行。我DataTable在 a 中View,但我需要使用 a 中的排序intViewModel

我可以在我public static int o { get; set; }的 . 然后我通过在 my 中实例化 my 来获取值,其中.dt.Rows.CountDataTableViewViewModelint numberOfRows = ViewName.o;

但这给了我总行数,而我需要“Column1”中每个不同值的行数。

我的问题是,我在哪里以及如何进行所需的排序?因为当我计算它们并将它们添加到int(在我的ViewModel)中时,没有办法知道它们曾经代表什么行,对吧?如果我尝试以某种方式对DataTable(in the View) 进行排序,我不知道如何引用不同的值。随着程序的使用,它们可能会不时变化,因此我无法对其进行硬编码。

评论建议改用查询,添加我的存储过程以帮助实施解决方案:

SET NOCOUNT ON
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER PROCEDURE [dbo].[myProcedure]
    @param myUserDefinedTableType readonly

AS
BEGIN TRANSACTION
    INSERT INTO [dbo].[myTable] (/* list of columns */)
        SELECT [Column1], /* this is the column I need to sort by */
               -- more columns
               -- the rest of the columns
        /* I do aggregations to my columns here, I am adding several thousands row to 20 summarized rows, so after this line, I can no longer get ALL the rows per "Column1", but only the summarized rows. How can I count the rows BEFORE I do the aggregations? */
        FROM @param

        GROUP BY [Column2], [Column1]
        ORDER BY [Column2], [Column1]

// Some UPDATE clauses

COMMIT TRANSACTION

标签: c#sortingdatatable

解决方案


我相信最明智的选择是在 db 方面采取行动。
假设您使用的是 SQL Server,查询应该是:

SELECT *, COUNT(*) OVER (PARTITION BY Column1) AS c
FROM Table1
ORDER BY c

此查询返回表“Table1”上的数据,以及表示“Column1”值计数的列“c”,每行。
最后,它会根据您的要求按“c”列对行进行排序。


编辑

为了完成这个任务,我将使用一个Common Table Expression

-- Code before INSERT...

;WITH CTE1 AS (  
    SELECT *,  
        COUNT(*) OVER (PARTITION BY [Column1]) AS c  
    FROM @param  
)  
INSERT INTO [dbo].[myTable] (/* list of columns - must add the column c */)  
SELECT [Column1],  
       [Column2],  
       [c],  
       -- aggregated columns    
FROM CTE1  
GROUP BY [Column2], [Column1], c  
      
-- Code after INSERT...  

在公用表表达式“CTE1”中,我选择@param 中的所有值,添加一个列“c”,其中每个列1 的计数。

注意:如果您有 5 行具有相同的 Column1 值,但 Column2 中有两个不同的值,则在 myTable 中您将有两行(因为 GROUP BY [Column2],[Column1]),两者都具有 c=5。
如果您想获得按 Column1 和 Column2 分组的计数,则必须按如下方式声明 c COUNT(*) OVER (PARTITION BY [Column1], [Column2]) AS c:.

我希望我很清楚,如果不是,我可以用不同的方式来解释它。


例子

CREATE TABLE myTable (col1 VARCHAR(50), col2 INT, col3 INT, c INT) 

CREATE TYPE myUserDefinedTableType AS TABLE (column1 VARCHAR(50), column2 INT,  column3 INT)  
DECLARE @param myUserDefinedTableType  
INSERT INTO @param VALUES ('A', 1, 4), ('A', 2, 3), ('A', 2, 6), ('B', 2, 3)  

;WITH CTE1 AS (
    SELECT *, COUNT(*) OVER (PARTITION BY [Column1]) AS c 
    FROM @param
)  
INSERT INTO [myTable]([col1], [col2], [col3], [c])  
SELECT [column1], [column2], 
    -- aggregated columns  
    MAX([column3]), 
    -- count
    [c]  
FROM CTE1  
GROUP BY [column2], [column1], c   

推荐阅读