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

如何用正则匹配尺寸并在SQL/C#中排序生成下拉选单

解决下拉菜单中板材尺寸排序问题(不破坏Value值)

推荐方案:从SQL查询层面实现智能排序

这是最稳妥的方案,直接从数据库获取排好序的数据,前端无需额外处理,完美避免前端排序导致的Value值异常问题。

原SQL的ORDER BY AV.AttrValue DESC是按字符串字典序排序,会导致"900900"排在"1500900"前面这类混乱情况。我们可以通过CASE WHEN逻辑区分尺寸类和非尺寸类值,对尺寸提取数值进行排序,非尺寸类按原字符串排序:

DECLARE @StockID int = 680 
DECLARE @VariationParent int = (SELECT TOP 1 StockParent_ParentId FROM StockVariations SV INNER JOIN FinGoodsParent FGP ON FGP.Id = SV.StockParent_ChildId WHERE StockParent_ChildId = @StockID AND SV.IsDeleted = 0 AND FGP.IsDeleted = 0 AND FGP.Publish = 1) 

SELECT DISTINCT 
    AV.ID, 
    AV.AttrValue, 
    AV.AttributeTypes_Id 'AttributeTypeID', 
    CAST(CASE WHEN SA.StockParent_Id = @StockID THEN 1 ELSE 0 END as BIT) 'IsDefault' 
FROM AttributeTypes AT 
INNER JOIN AttributeValues AV ON AV.AttributeTypes_Id = AT.Id 
INNER JOIN StockParent_AttributeValues SA on SA.AttributeValue_Id = AV.Id 
INNER JOIN FinGoodsParent FGP ON FGP.Id = SA.StockParent_Id AND FGP.IsDeleted = 0 AND FGP.Publish = 1 
WHERE SA.StockParent_Id IN (
    SELECT SV.StockParent_ChildId 
    FROM StockVariations SV 
    INNER JOIN FinGoodsParent FGP ON FGP.Id = SV.StockParent_ChildId AND FGP.IsDeleted = 0 AND FGP.Publish = 1 
    WHERE SV.StockParent_ParentId = @VariationParent AND SV.IsDeleted = 0
) 
AND SA.IsDeleted = 0 AND AT.IsDeleted = 0 AND AV.IsDeleted = 0 
-- 核心修改:智能排序逻辑
ORDER BY 
    -- 优先按尺寸的第一个数值排序(非尺寸类给大数,排后面)
    CASE 
        WHEN CHARINDEX('*', AV.AttrValue) > 0 OR CHARINDEX('x', AV.AttrValue) > 0 THEN 
            CAST(LEFT(AV.AttrValue, CHARINDEX(CASE WHEN CHARINDEX('*', AV.AttrValue) > 0 THEN '*' ELSE 'x' END, AV.AttrValue) - 1) AS INT)
        ELSE 999999
    END ASC,
    -- 尺寸的第二个数值排序
    CASE 
        WHEN CHARINDEX('*', AV.AttrValue) > 0 OR CHARINDEX('x', AV.AttrValue) > 0 THEN 
            CAST(SUBSTRING(AV.AttrValue, CHARINDEX(CASE WHEN CHARINDEX('*', AV.AttrValue) > 0 THEN '*' ELSE 'x' END, AV.AttrValue) + 1, LEN(AV.AttrValue)) AS INT)
        ELSE 0
    END ASC,
    -- 非尺寸类按原文本排序
    AV.AttrValue ASC

逻辑说明:

  • 先判断AttrValue是否包含*或x(尺寸标识),如果是则提取前后的数字转为整数,先按第一个数字升序,再按第二个数字升序。
  • 非尺寸类(如颜色、米数)会被分配一个大数值(999999),排在尺寸类之后,然后按原字符串自然排序。
  • 完全不需要额外的排序表,直接在查询中处理所有场景。

前端备选方案(若无法修改SQL)

如果暂时不能调整SQL,可以修改jQuery代码,绝不修改Option的Value值,仅根据文本内容排序Option元素,同时保留原选中状态:

$(document).ready(function() {
    // 先保存每个下拉框的原选中值,避免排序后丢失
    $(".variation-picker").each(function() {
        $(this).data("original-selected", $(this).val());
    });

    // 对每个下拉框进行排序
    $(".variation-picker").each(function() {
        const $select = $(this);
        const $options = $select.find("option").sort((a, b) => {
            const aText = $(a).text().trim();
            const bText = $(b).text().trim();
            
            // 判断是否为标准尺寸格式(数字+*或x+数字)
            const isASize = /^\d+[*x]\d+$/.test(aText);
            const isBSize = /^\d+[*x]\d+$/.test(bText);

            if (isASize && isBSize) {
                // 拆分尺寸为两个数字维度
                const [a1, a2] = aText.split(/[*x]/).map(Number);
                const [b1, b2] = bText.split(/[*x]/).map(Number);
                
                // 先比较第一个维度,再比较第二个维度
                if (a1 !== b1) return a1 - b1;
                return a2 - b2;
            } else if (isASize) {
                // 尺寸类优先排在前面
                return -1;
            } else if (isBSize) {
                return 1;
            } else {
                // 非尺寸类按文本自然排序
                return aText.localeCompare(bText);
            }
        });

        // 重新渲染下拉框并恢复原选中值
        $select.empty().append($options);
        const originalValue = $select.data("original-selected");
        if (originalValue) $select.val(originalValue);
    });
});

改进点:

  • 完全不触碰Option的value属性,彻底解决Ajax获取错误值的问题。
  • 智能区分尺寸类和非尺寸类,尺寸按数值逻辑排序,非尺寸按文本排序。
  • 提前保存原选中状态,排序后自动恢复,避免用户选中的选项丢失。

C#代码无需修改

无论使用哪种方案,你的C#渲染代码都不需要调整:如果用SQL方案,数据已经排好序,直接循环渲染即可;如果用前端方案,前端会自动处理排序,C#保持原样输出就行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 06:42:08