如何将宽度和高度大小与 Regex 表达式匹配并在 SQL 或 C# 中使用 Sort By 来构建下拉列表?

Posted

技术标签:

【中文标题】如何将宽度和高度大小与 Regex 表达式匹配并在 SQL 或 C# 中使用 Sort By 来构建下拉列表?【英文标题】:How to match a width and height size with a Regex expression and use Sort By in SQL or C# to build a drop-down? 【发布时间】:2019-12-07 21:48:46 【问题描述】:

我有一个 SQL 查询,它将检索下表,但我想在下拉选择中按降序(从小到大)正确排序板尺寸。我正在使用 C# 从对象构建 Dropdown 选择。

这是当前 SQL 查询返回的内容。

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 AV.AttrValue DESC

我尝试使用有效的 JQuery 代码,但它替换了 dropdown 选择的值,这将阻止我的 Ajax 功能从检索正确的信息。

这里是 JQuery 代码,它可以工作,但我想在 SQLC# 中执行此操作。下面的代码将对任何带有数字的东西进行正则表达式匹配,并去掉第一个数字并比较大小。必须注意,有时数据库中的大小可以用 x 而不是 * 分隔值。

<select class="variation-picker">   
    <option value="42">1500*900</option>
    <option value="48">900*900</option>
    <option value="46">2400*600</option>
    <option value="49">600*600</option>
</select>

$( document ).ready(function() 
    $(".variation-picker").html($(".variation-picker option").val(function () 
        return this.text.match(/\d+/);
    ).sort(function (a, b) 
        var a = parseInt(a.value, 10), b = parseInt(b.value, 10);
        return a < b ? -1 : 1;
     ));

    $('.variation-picker').find('option[selected="selected"]').each(function () 
        $(this).prop('selected', true);
    );

);

这是我用来构建变体选择下拉菜单的 C# 代码。 AttrValue 列还可以包含诸如colourmeters 之类的值,因此它不应仅与数字相关联。我真的不想创建一个包含订单优先级等的单独表格。

if (ProductDetails.ProductVariations?.Count > 0)
        
            var html = new System.Text.StringBuilder();
            var colCount = 0;

            //Build the variations dropdowns

            ProductDetails.ProductVariations.ForEach(p =>
            
                if (colCount == 2)
                
                    colCount = 0;
                    html.AppendLine("</div>");
                    html.AppendLine("<div class='row'>");
                

                html.AppendLine("<div class='col-md-6 single-variation-div'>");
                html.AppendLine($"<span class='text_select' id='v_p.ID'>p.Name</span><br />");
                html.AppendLine("<select class='selectpicker variation-picker' data-width='300px' onchange='javascript:ChangeProductVariance();'> ");
                p.ProdVariationValues.ForEach(v => html.AppendLine($"<option value='v.ID'  (v.IsDefault ? "selected='selected'" : "") >v.AttrValue</option>"));
                html.AppendLine("</select><br/>");
                html.AppendLine("</div>");

                colCount++;
            );

            ProductVarienceHTML = html.ToString();
        
        else
        
            ProductVarienceHTML = "";
        

【问题讨论】:

我会先开始处理您的数据库。在一列中存储宽度、高度和测量单位违反了第一范式。您应该将它们分成三列,高度、宽度和测量单位(然后您也可以将它们放入另一个表格并参考) 感谢您的回答。我们将尺寸存储在实际产品表上。我们将其用作搜索参数、分组等的元标记。我们将其用作分组标记。 AttrValue 可以包含颜色和其他产品属性等文本。 【参考方案1】:

我建议你从表结构中解决它:添加具有(INT)数据类型的高度和宽度的列,然后按(高度*宽度)排序

【讨论】:

【参考方案2】:

以防万一您无法通过添加 heightwidth 列来更改数据库架构:

假设这是您的架构,只是为了简化您的原始查询:

CREATE TABLE attributes
    ([AttrValue] varchar(13))
;

INSERT INTO attributes
    ([AttrValue])
VALUES
    ('900*900mm'),
    ('1200*900mm'),
    ('1200*1200mm')
;

让我们创建一个按height * width 降序排序的查询:

SELECT
  attrValue,
  CONVERT(int, (select top 1 value from STRING_SPLIT(attrValue, '*'))) as [leftAttrValue],
  CONVERT(int, (select top 1 LEFT(value, LEN(value) - 2) from STRING_SPLIT(attrValue, '*') where value LIKE '%mm')) as [rightAttrValue]
FROM
  attributes
ORDER BY 
    CONVERT(int, (select top 1 value from STRING_SPLIT(attrValue, '*'))) * 
    CONVERT(int, (select top 1 LEFT(value, LEN(value) - 2) from STRING_SPLIT(attrValue, '*') where value LIKE '%mm'))  DESC
  ;

这个查询的结果是这样的:

|   attrValue | leftAttrValue | rightAttrValue |
|-------------|---------------|----------------|
| 1200*1200mm |          1200 |           1200 |
|  1200*900mm |          1200 |            900 |
|   900*900mm |           900 |            900 |

您可以在此 SQL Server 小提琴中进行测试:http://sqlfiddle.com/#!18/691b3/11

所以,我们现在将根据您的问题进行调整:

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 
      CONVERT(int, (select top 1 value from STRING_SPLIT(AV.AttrValue, '*'))) * 
      CONVERT(int, (select top 1 LEFT(value, LEN(value) - 2) from STRING_SPLIT(AV.AttrValue, '*') where value LIKE '%mm'))  
    DESC

【讨论】:

感谢您的详细解释。欣赏它。【参考方案3】:

最好的解决方案和最快的解决方案就是按照@Ahmad Alkaraki 所说的去做。

如果你不能,那么这是一个可行的解决方案。 SPLIT AttrValue 并将其转换为 int,然后提取 widthheight,然后提取 size

看看order by

我不确定你的 mssql 中是否存在 func LAST EXIST,但你得到了 idee

 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 ((SELECT top 1 cast(value as int) FROM STRING_SPLIT(AT.AttrValue, "*") *
            (SELECT cast(LAST(value)) FROM STRING_SPLIT(AT.AttrValue, "*")) DESC

【讨论】:

以上是关于如何将宽度和高度大小与 Regex 表达式匹配并在 SQL 或 C# 中使用 Sort By 来构建下拉列表?的主要内容,如果未能解决你的问题,请参考以下文章

css 这定义了在分配剩余空间之前元素的默认大小。主尺寸值使其与宽度或高度匹配

如何在颤动中创建具有固定宽度和高度的颜色框?

如何更改屏幕方向并获得更改的画布大小

UILabel 找到适合宽度的高度

CSS:如何设置相对于父高度的图像大小?

如何在绘制之前获取调整大小的自定义视图的宽度和高度