简体   繁体   English

如何使用Regex表达式匹配宽度和高度大小,以及如何在SQL或C#中使用“排序依据”来构建下拉列表?

[英]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?

I've a SQL query which will retrieve the following table, but I want to order the Board size correctly in Descending order (Small to Large) in a drop-down selection. 我有一个SQL查询,它将检索下表,但我想在下拉选择中以降序(从小到大)正确地排列板子的大小。 I'm using C# to build the Dropdown selection from the object. 我正在使用C#从对象构建Dropdown选择。

This is what the current SQL query returns. 这是当前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

I've tried to use JQuery code which works, but it replaces the value of the dropdown selection which will prevent my Ajax function from retrieving the correct information. 我尝试使用有效的JQuery代码,但它替换了下拉选择的值,这将阻止我的Ajax函数检索正确的信息。

Here is the JQuery code which kind of works, but I want to either do this in SQL or C# . 这是可以工作的JQuery代码,但是我想用SQLC#进行 The code below will do a regex match for anything with numbers and strip out the first number and compare the size. 下面的代码将对带有数字的任何内容进行正则表达式匹配,并去除第一个数字并比较大小。 It must be noted that sometimes the sizes in the database can have an x instead of a * separating the values. 必须注意的是,有时数据库中的大小可以用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);
    });

});

This is the C# code I'm using in order to build the variation selection dropdowns . 这是我用来构建变体选择下拉列表的C#代码。 The AttrValue column can also contain values such as colour or meters , so it shouldn't just be tied to numeric. AttrValue列还可以包含值,如colourmeters ,所以它不应该仅仅依赖于数值。 I don't really want to create a separate table with order priorities and etc. 我真的不想创建带有订单优先级等的单独表格。

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 = "";
        }

我建议您通过以下方法从表结构中解决该问题:通过添加具有(INT)数据类型的高度和宽度的列,然后按(height * width)进行排序

The best solution and fastest solution is doing what @Ahmad Alkaraki said. 最好的解决方案和最快的解决方案是@Ahmad Alkaraki所说的。

Incase you cant then this is a solution that could work. 如果您不能这样做,那么这是一个可行的解决方案。 SPLIT the AttrValue and convert it to int, then extraxt width and height , there after extract the size SPLIT AttrValue并将其转换为int,然后extext widthheight ,然后提取size

Have a look at order by 看看order by

Im not sure if func LAST EXIST in your mssql but you get the idee 我不确定在您的mssql中func LAST EXIST是否存在,但是您知道了

 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

Just in case you can't change your database schema by adding height and width columns: 万一您不能通过添加heightwidth列来更改数据库架构,以防万一:

Let's assume that this is your schema, just for simplifying a little your original query: 假设这是您的模式,只是为了简化您的原始查询:

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

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

Let's create a query that sort by the height * width descending: 让我们创建一个按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
  ;

The result of this query is this: 该查询的结果是这样的:

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

You can test this in this SQL Server fiddle: http://sqlfiddle.com/#!18/691b3/11 您可以在以下SQL Server小提琴中对此进行测试: http ://sqlfiddle.com/#!18/ 691b3/11

So, we will adapt this now to your problem: 因此,我们现在将对此进行调整以解决您的问题:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM