代码之家  ›  专栏  ›  技术社区  ›  Sisiutl

我需要一个“模糊”查询来获得给定维度上下的产品

  •  0
  • Sisiutl  · 技术社区  · 16 年前

    结果应始终显示一定尺寸的所有产品;换言之,如果向上或向下移动到下一个尺寸将导致超过50种产品,请全部展示-不要停留在50。

    示例:假设有25种不同的尺寸,每种尺寸有20种产品。用户要求12号。我们需要降三号,升三号,每个方向至少50号。查询应返回所有大小为12的产品,以及大小为9、10、11、13、14和15的产品。查询将返回总共140个产品(20个12号加上60个以上和60个以下) 不幸的是,这些大小并不像我的例子中那样是好的整数。它们是任意的十进制值。

    实现这一点的Linq到SQL查询将非常酷,但也欢迎使用纯SQL或C#。 (我的环境是C#,SQL Server 2005)

    2 回复  |  直到 16 年前
        1
  •  1
  •   Chris Baxter    16 年前

    下面是一个示例SQL语句(用于mysql),它应该做您想要做的事情。但是,根据您的过程正在执行的其他操作,您可能会发现在C代码中执行某些处理会更快:

    SELECT 
        *
    FROM
        products
    WHERE 
        size = [[desired_size]] OR 
        size IN (
             SELECT DISTINCT 
                 size 
             FROM 
                 products
             WHERE
                 size > [[desired_size]]
             ORDER BY 
                 size
             LIMIT 50
        )
        OR
        size IN (
             SELECT DISTINCT 
                 size 
             FROM 
                 products
             WHERE
                 size < [[desired_size]]
             ORDER BY 
                 size DESC
             LIMIT 50
        )
    

    我将从开头开始解释(并用您的示例说明值)。。。

    首先,我们需要生成下50个较大(或较小)项目的列表。以下查询应执行此操作:

    SELECT * FROM products WHERE size > 12 ORDER BY size LIMIT 50
    

    您可以在VisualStudioSQL编辑器中尝试此操作,并查看它返回哪些行。

    SELECT DISTINCT size...
    

    所以,现在我们只看“size”列,我们使用DISTINCT关键字来避免重复值

    现在,查询只返回列表:(13、14、15)

    我们进行了类似的查询,以获得接下来50个较小的项目:

    SELECT DISTINCT size FROM products WHERE size < 12 ORDER BY size DESC LIMIT 50
    

    在这种情况下,此查询将返回列表(11、10、9)

    如果我们使用这两个列表将其全部放在外部查询中,我们会得到:

    SELECT
      *
    FROM
      products
    WHERE
      size = 12 OR
      size IN (13, 14, 15) OR
      size IN (11, 10, 9)
    

    我希望这是有意义的:——)

        2
  •  0
  •   Basic    16 年前

    您遇到的问题似乎是无法轻松定义结果集的边界条件。

    显然,您可以轻松做到:

    Get me everything of size X
    Get me 50 of size >X
    Get me 50 of size <X
    

    也许

    比如:

    Dim ExactSize = 1.1
    
    Dim MaxSizeRecord = MyRepository.Get(function(x) x.Size > ExactSize).OrderBy(function(y) y.Size).Skip(50).First
    Dim MinSizeRecord = MyRepository.Get(function(x) x.Size < ExactSize).OrderByDescending(function(y) y.Size).Skip(50).First
    
    Dim FinalResults = MyRepository.Get(function(x) x.Size >= MinSizeRecord.Size and X.Size <= MaxSizeRecord.Size)
    

    我还没有足够的勇气去了解林克是否。。。

    Dim MaxSize = MyRepository.Get(function(x) x.Size > ExactSize).OrderBy(function(y) y.Size).Skip(50).First.Size
    Dim MinSize = MyRepository.Get(function(x) x.Size < ExactSize).OrderByDescending(function(y) y.Size).Skip(50).First.Size
    
    Dim FinalResults = MyRepository.Get(function(x) x.Size >= MinSize and X.Size <= MaxSize)
    

    …将生成相同的SQL-它当然更具可读性,但LINQ可能会在值存储在Double中时立即执行Min/Max查询-通过定义MinSize/MaxSize的类型 它会把它当作一个可交换的(双倍的)。

    在可读性稍差的情况下,使用记录而不是双精度记录可以保证它被视为一个查询,而不是一个值。