You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TSQL中为200亿行MSSQL表生成车牌0/O全排列构建WHERE IN子句

处理MSSQL中车牌0/O混淆的高效查询方案

针对200亿行的大表,不能用REPLACE(会触发全表扫描),需要生成目标车牌所有0/O位置的替换组合,用精确匹配的WHERE IN来利用索引,具体实现如下:

核心思路

找出目标车牌中所有是0或O的位置,为每个位置生成0和O两种可能,组合出所有候选车牌值,最终用这些值做IN子句的精确匹配,这样能触发车牌列的索引扫描,大幅提升查询效率。

TSQL实现代码

以下代码以目标车牌'0OABC'为例,生成所有4种组合:

DECLARE @TargetPlate NVARCHAR(20) = '0OABC';

-- 递归CTE生成所有0/O替换组合
WITH PlateCTE AS (
    -- 初始化:拆分第一个字符
    SELECT 
        CAST(CASE WHEN SUBSTRING(@TargetPlate, 1, 1) IN ('0', 'O') THEN '0' ELSE SUBSTRING(@TargetPlate, 1, 1) END AS NVARCHAR(20)) AS Plate,
        CAST(CASE WHEN SUBSTRING(@TargetPlate, 1, 1) IN ('0', 'O') THEN 'O' ELSE SUBSTRING(@TargetPlate, 1, 1) END AS NVARCHAR(20)) AS AltPlate,
        1 AS Position
    UNION ALL
    -- 递归处理后续每个字符
    SELECT
        CAST(p.Plate + CASE WHEN SUBSTRING(@TargetPlate, c.Position + 1, 1) IN ('0', 'O') THEN '0' ELSE SUBSTRING(@TargetPlate, c.Position + 1, 1) END AS NVARCHAR(20)),
        CAST(p.Plate + CASE WHEN SUBSTRING(@TargetPlate, c.Position + 1, 1) IN ('0', 'O') THEN 'O' ELSE SUBSTRING(@TargetPlate, c.Position + 1, 1) END AS NVARCHAR(20)),
        c.Position + 1
    FROM PlateCTE c
    CROSS APPLY (
        VALUES (c.Plate), (c.AltPlate)
    ) p(Plate)
    WHERE c.Position < LEN(@TargetPlate)
),
-- 收集所有唯一的组合
AllPlates AS (
    SELECT DISTINCT Plate FROM PlateCTE
    UNION
    SELECT DISTINCT AltPlate FROM PlateCTE
)
-- 生成最终查询的IN子句值,或者直接用于查询
SELECT Plate FROM AllPlates;

执行后会输出:

00ABC
0OABC
OOABC
O0ABC

直接用于查询的方式

如果要直接查询表,可把生成的组合作为IN的参数:

DECLARE @TargetPlate NVARCHAR(20) = '000XYZ';

WITH PlateCTE AS (
    SELECT 
        CAST(CASE WHEN SUBSTRING(@TargetPlate, 1, 1) IN ('0', 'O') THEN '0' ELSE SUBSTRING(@TargetPlate, 1, 1) END AS NVARCHAR(20)) AS Plate,
        CAST(CASE WHEN SUBSTRING(@TargetPlate, 1, 1) IN ('0', 'O') THEN 'O' ELSE SUBSTRING(@TargetPlate, 1, 1) END AS NVARCHAR(20)) AS AltPlate,
        1 AS Position
    UNION ALL
    SELECT
        CAST(p.Plate + CASE WHEN SUBSTRING(@TargetPlate, c.Position + 1, 1) IN ('0', 'O') THEN '0' ELSE SUBSTRING(@TargetPlate, c.Position + 1, 1) END AS NVARCHAR(20)),
        CAST(p.Plate + CASE WHEN SUBSTRING(@TargetPlate, c.Position + 1, 1) IN ('0', 'O') THEN 'O' ELSE SUBSTRING(@TargetPlate, c.Position + 1, 1) END AS NVARCHAR(20)),
        c.Position + 1
    FROM PlateCTE c
    CROSS APPLY (
        VALUES (c.Plate), (c.AltPlate)
    ) p(Plate)
    WHERE c.Position < LEN(@TargetPlate)
),
AllPlates AS (
    SELECT DISTINCT Plate FROM PlateCTE
    UNION
    SELECT DISTINCT AltPlate FROM PlateCTE
)
SELECT * FROM plates
WHERE plate IN (SELECT Plate FROM AllPlates);

关键优势

  • 避免全表扫描:IN子句的精确匹配可以利用车牌列的非聚集索引,对于200亿行的大表,索引扫描的效率远高于REPLACE导致的表扫描。
  • 覆盖所有可能:递归CTE会生成所有0/O位置的替换组合,不会遗漏任何可能的误识别情况。

内容的提问来源于stack exchange,提问作者Roger

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 11:41:13