如何根据特定参数对计数的 DataTable 行进行排序

How can I sort counted DataTable rows according to specific parameter

我正在尝试使用 dataTable.Rows.Count,但根据特定参数对结果进行排序。 该参数在我的 DataTable 中是“Column1”。这样输出就只给我与该不同值有关的行。 我的 DataTableView 中,但我需要在 ViewModel.

中使用排序后的 int

我可以用 public static int o { get; set; } 和一个 dt.Rows.Count 在我的 DataTable 中。然后我通过在我的 ViewModel 中实例化我的 View 来获取值,其中 int numberOfRows = ViewName.o;.

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

我的问题是,在哪里以及如何进行所需的排序? 因为当我尽可能地计算它们并将它们添加到 int(在我的 ViewModel 中)时,没有办法知道它们曾经代表哪一行,对吧? 如果我尝试以某种方式在 DataTable(在 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

我认为最明智的选择是在数据库端进行操作。
假设您使用的是 SQL 服务器,查询应该是:

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

此查询 returns 您的 table“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...  

在通用 Table 表达式“CTE1”中,我 select @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   
DataView dv = dt.DefaultView;
dv.Sort = "SName ASC"; -- your column name
DataTable dtsorted = dv.ToTable();

 DataTable dtsorted = dv.ToTable(true, "Sname","Surl" ); //return distinct rows