繁体   English   中英

WHERE子句中的LIMIT SQL?

[英]LIMIT SQL within WHERE clause?

是否可以在sql的WHERE子句中放置限制?

表名称: _mct_dot

列: a_ID (auto inc) number (index) qty (index) com_val

SELECT
        *
    FROM
        _mct_dot
    WHERE
        (
            number = 4
            OR
            number = 7
            OR
            number = 13
        )
        AND 
        (
            qty = 3
            OR
            qty = 5
            OR
            qty = 7
        )
    ORDER BY
        number ASC, qty ASC

因此,上面的查询实际上将返回按顺序分组的数组。 但是,它将提取值3、5和7的所有“数量”。我需要的是“数量” 3、5和7的5个结果的样本。 我需要结果看起来像:

'number' 4's with 'qty' = 3's where 'qty' limited to max 5 
'number' 4's with 'qty' = 5's where 'qty' limited to max 5 
'number' 4's with 'qty' = 7's where 'qty' limited to max 5 
'number' 7's with 'qty' = 3's where 'qty' limited to max 5 
'number' 7's with 'qty' = 5's where 'qty' limited to max 5 
'number' 7's with 'qty' = 7's where 'qty' limited to max 5 
'number' 13's with 'qty' = 3's where 'qty' limited to max 5 
'number' 13's with 'qty' = 5's where 'qty' limited to max 5 
'number' 13's with 'qty' = 7's where 'qty' limited to max 5 

不,不可能在WHERE子句中添加LIMIT子句。

可以实现所需的结果集,但是执行此操作的SQL并不是很漂亮。 这将需要JOIN,相关子查询或内联视图。


如果_mct_dot中的行有一个“顺序”,则可以使用相关子查询来检查拉出的行“之前”的行数,并仅获取少于四行的行。

SELECT d.*
  FROM _mct_dot d
  JOIN ( SELECT n.number
              , q.qty
           FROM (SELECT 4 AS `number` UNION ALL SELECT 7 UNION ALL SELECT 13) n
          CROSS
           JOIN (SELECT 3 AS `qty` UNION ALL SELECT 5 UNION ALL SELECT 7) q
       ) p
    ON p.number = d.number
   AND p.qty = d.qty
   AND 5 > ( SELECT SUM(1)
               FROM _mct_dot c
              WHERE c.number = d.number
                AND c.qty = d.qty
                AND c.a_ID < d.a_ID
           )
 ORDER BY ...

相关的子查询可能会被执行很多次,因此为了获得最佳性能,您将需要一个索引,该索引的前导a_id numberqty并包括a_id列。

要么:

... ON `_mct_dot` (`number`, `qty`, `a_ID`)

要么

... ON `_mct_dot` (`qty`, `number`, `a_ID`)

另一个选择是使用MySQL用户变量来模拟row_number()分析函数,如下所示:

SELECT t.*
  FROM ( SELECT d.a_ID
              , IF(d.number = @prev_number AND d.qty = @prev_qty
                  , @rn := @rn + 1
                  , @rn := 1
                ) AS rn
              , @prev_number := d.number
              , @prev_qty := d.qty
           FROM (SELECT @prev_number := NULL, @prev_qty := NULL, @rn := 0 ) i
          CROSS 
           JOIN ( SELECT n.number
                       , q.qty
                    FROM (SELECT 4 AS `number` UNION ALL SELECT 7 UNION ALL SELECT 13) n
                   CROSS
                    JOIN (SELECT 3 AS `qty` UNION ALL SELECT 5 UNION ALL SELECT 7) q
                ) p
           JOIN _mct_dot d
             ON d.number = p.number
            AND d.qty = p.qty
          ORDER BY d.number, d.qty
       ) s
  JOIN _mct_dot t
    ON t.a_ID = s.a_ID
 WHERE s.rn <= 5 
 ORDER BY t.number ASC, t.qty ASC

(这些查询仅在桌面进行检查;尚未设置SQL Fiddle演示。)

跟进

对于第一个查询,我只使用了一个内联视图(别名为“ p”),该视图生成了所请求的所有成对的numberqty对的集合。

我们可以使用JOIN操作从_mct_dot表中找到与每对匹配的所有行。

棘手的部分是相关子查询。 (我们可以使用两种方法。)上面查询中的方法是获取具有匹配的“数字”和“数量”但其ID值小于该ID值的行的“计数”当前行,基本上是找出当前行“之前”有多少行。 我们将其与文字5进行比较,因为我们只想返回每个组中的前5行。


对于第二个查询,

由于i正在初始化一些MySQL用户变量,因此内联视图具有别名。 我们真的不在乎查询返回什么,除了它只返回一行(因为我们在JOIN操作中引用它)...我们真正感兴趣的是在变量的开头初始化变量。执行。 发生这种情况的原因是,在执行引用该视图的外部查询之前,MySQL实现了内联视图(派生表)。

别名为p的内联视图为我们提供了要检索的number,qtynumber,qty ,我们对_mct_dot使用JOIN操作来获取匹配的行。

内联视图中别名为s的“技巧”是使用MySQL用户变量。 我们正在根据前一行的值检查当前值...如果数量和数量匹配,那么我们在同一个“组”中,因此我们可以将行计数器增加1。这两个值都会更改,然后是一个新组,所以我们将行号计数器重置为1,因为当前行是新组中的“第一”行。

我们可以对内联视图s运行查询,并看到我们正在为每个组获取行号( rn col)1、2、3等。

然后,最外面的查询仅过滤rn号大于5的所有行。 实际上,从s ,我们仅返回该行的唯一标识符; 该最外面的查询也在执行基于唯一ID的JOIN操作来检索整行。


正如我在回答的顶部提到的那样,执行此操作的SQL并不漂亮。 (解开这些查询的工作确实需要一些工作。)

由于不确定性不明确,我不确定我是否正确理解了您的问题,但是根据我的理解,我认为您可以尝试执行以下操作:

SELECT     attribute_number,
           grade_number //, other columns

FROM       _mct_dot
WHERE      (number = 4 AND qty IN (3, 5 ,7))
OR         (number = 7 AND qty IN (3, 5, 7))
OR         (number = 13 AND qty IN (3, 5, 7))
GROUP BY   attribute_number, grade_number
ORDER BY   attribute_number ASC, grade_number ASC
LIMIT      5

希望这可以帮助!!!

暂无
暂无

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

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