Oracle按照特定列值排序和C#统计特定列值的所有行

1、数据源

Oracle 表 ID,TEST_ITEM 数据如下

ID TEST_ITEM
1 通孔孔铜
2 表面铜厚1
3 表面铜厚2
4 L02
5 L03
6 线面实测
7 线角实测
8 L01-L02
9 L02-L03
10 L03-L04

2、Oracle实现如下需求

要想让表面铜厚1 排在L02,L03的前面,表面铜厚2 排在L02,L03的后面

在 Oracle SQL 中,要按照 "表面铜厚1" 排在 "L02"、"L03" 前面,而 "表面铜厚2" 排在 "L02"、"L03" 后面 的顺序排序,可以使用 CASE WHEN 语句自定义排序优先级。以下是实现方法:

SQL 排序方案

sql 复制代码
SELECT ID, TEST_ITEM
FROM your_table
ORDER BY 
    CASE 
        WHEN TEST_ITEM = '表面铜厚1' THEN 1       -- 表面铜厚1 排最前
        WHEN TEST_ITEM IN ('L02', 'L03') THEN 2   -- L02/L03 排中间
        WHEN TEST_ITEM = '表面铜厚2' THEN 3       -- 表面铜厚2 排后面
        ELSE 4                                    -- 其他项默认排序
    END,
    ID;  -- 相同优先级时按ID排序

执行结果示例

ID TEST_ITEM
2 表面铜厚1
4 L02
5 L03
3 表面铜厚2
1 通孔孔铜
6 线面实测
7 线角实测
8 L01-L02
9 L02-L03
10 L03-L04

关键点说明

  1. 优先级控制

    • 表面铜厚1 → 优先级 1(最前)
    • L02/L03 → 优先级 2(中间)
    • 表面铜厚2 → 优先级 3(后面)
    • 其他项 → 优先级 4(按原始顺序)
  2. 次级排序
    ID 作为第二排序条件,确保相同优先级的记录按插入顺序排列。

  3. 扩展性

    如需处理更复杂的规则(如 L01-L02 需单独排序),可扩展 CASE WHEN 条件:

    sql 复制代码
    CASE 
        WHEN TEST_ITEM = '表面铜厚1' THEN 1
        WHEN TEST_ITEM LIKE 'L%' AND TEST_ITEM NOT LIKE '%-%' THEN 2  -- 仅匹配L02/L03
        WHEN TEST_ITEM = '表面铜厚2' THEN 3
        ELSE 4
    END

此方案灵活满足定制化排序需求,同时保持代码清晰易维护。

3、C#统计特定列值的所有行

在 C# 中统计 DataTable 中类似 L02L03 格式的行数(即 L 开头 + 数字结尾),可通过以下方法实现:


方法 1:使用 DataView 正则过滤(推荐)

csharp 复制代码
using System.Data;
using System.Text.RegularExpressions;

DataTable dt = GetYourDataTable(); // 假设已加载数据

// 正则匹配 L + 数字(如 L02、L03、L99)
DataView dv = new DataView(dt);
dv.RowFilter = "REGEX_LIKE(TEST_ITEM, '^L\\d+$')"; // 需自定义函数(见下方补充说明)

int count = dv.Count;
Console.WriteLine($"L开头数字结尾的行数: {count}");

补充说明
DataView 原生不支持正则,需通过 DataTableSelect 方法或遍历实现正则匹配(见方法2)。


方法 2:遍历 + 正则匹配(通用)

csharp 复制代码
int count = 0;
Regex regex = new Regex(@"^L\d+$"); // 匹配 L + 数字

foreach (DataRow row in dt.Rows)
{
    if (regex.IsMatch(row["TEST_ITEM"].ToString()))
    {
        count++;
    }
}

Console.WriteLine($"L开头数字结尾的行数: {count}");

方法 3:LINQ + 正则(简洁版)

csharp 复制代码
using System.Linq;

int count = dt.AsEnumerable()
    .Count(row => Regex.IsMatch(row.Field<string>("TEST_ITEM"), @"^L\d+$"));
Console.WriteLine($"L开头数字结尾的行数: {count}");

输出示例

若数据包含:

  • L02L03L04L01-L02(不符合)、表面铜厚1(不符合)

结果

复制代码
L开头数字结尾的行数: 3

扩展:统计特定范围(如 L01-L99)

csharp 复制代码
Regex regex = new Regex(@"^L(0[1-9]|[1-9]\d)$"); // 匹配 L01-L99
int count = dt.AsEnumerable()
    .Count(row => regex.IsMatch(row.Field<string>("TEST_ITEM")));

关键点

  1. 正则表达式
    • ^L\d+$:严格匹配 L + 1个或多个数字。
    • 排除 L01-L02 这类复合值(需调整正则逻辑)。
  2. 性能 :大数据量时推荐 DataView 或索引优化。

根据需求选择最适合的方案即可!