【问题标题】:MySQL first digit from integer in WHERE clauseMySQL WHERE 子句中整数的第一个数字
【发布时间】:2014-09-28 05:54:11
【问题描述】:

我正在四处寻找这个解决方案,但没有任何结果。

我有类别和子类别。它们由整数表示,如下所示:

1 -> high level
    10 -> sub
    11 -> sub
    12 -> sub
2 -> high level
    20 -> sub
    21 -> sub

...等等。因此,要搜索高级类别并返回其子类别,我需要搜索第一个数字。首先猜测是将其转换为字符串并搜索其子字符串。还有更简洁的方法吗?

【问题讨论】:

  • “我需要搜索第一个数字” – 你呢?至少从您的示例数据来看,您的子类别每个不能超过 10 个,因此过滤 >= 10 AND <= 19 应该可以工作......
  • 所有子类别都只有 2 位数字吗?如果是这样,xy / 10 会给你x

标签: mysql search optimization where


【解决方案1】:

如果类别 ID 有任意位数,您也可以通过一点数学来完成:

SELECT CAST(id / POW(10, CAST(LOG10(id) AS SIGNED)) AS SIGNED)

;)

开个玩笑,去LEFT(id, 1)

MID(id, position, 1),检索其他数字。

【讨论】:

  • 哈哈大笑,谢谢!现在我可能会暂时采用这种方式
  • @Meowts 请注意,这种方法不能很好地扩展。使用WHERE id LIKE '1%'as suggested by Marcus Adams 进行搜索将能够使用索引,而WHERE LEFT(id, 1) 则不能。但是不可能使用索引来检索(例如)第二个数字(例如WHERE id LIKE '?1%')。有many other, smarter ways代表RDBMS中的分层数据。
【解决方案2】:

您可以使用LEFT() 函数返回最左边的字符:

SELECT LEFT(category, 1)

如果是整数,MySQL 会自动将列值转换为字符串。

您还可以使用通配符和LIKE 进行比较:

SELECT category LIKE '1%'

但是,如果将类别视为字符串,请考虑将其设为字符串,然后 MySQL 可以在像这样选择时在 LIKE 示例中利用 category 上的索引:

SELECT * FROM categories WHERE category LIKE '1%'

【讨论】:

    【解决方案3】:

    你也可以在整数上使用 like :

    MariaDB [sometest]> desc cat;
    +-------+--------------+------+-----+---------+-------+
    | Field | Type         | Null | Key | Default | Extra |
    +-------+--------------+------+-----+---------+-------+
    | id    | int(11)      | YES  |     | NULL    |       |
    | lib   | varchar(255) | YES  |     | NULL    |       |
    +-------+--------------+------+-----+---------+-------+
    2 rows in set (0.01 sec)
    
    MariaDB [sometest]> select * from cat where id like '1%';
    +------+------------+
    | id   | lib        |
    +------+------------+
    |    1 | high level |
    |   10 | 1 sub 0    |
    |   11 | 1 sub 1    |
    |   12 | 1 sub 2    |
    +------+------------+
    4 rows in set (0.00 sec)
    
    MariaDB [sometest]> 
    

    但是,我希望我们的子类别永远不会超过 10 个类别。 您可能应该重新审视您的表格布局,并使用自引用记录:

    MariaDB [sometest]> create table self (id int not null auto_increment primary key, parent_id int, lib varchar(255));
    Query OK, 0 rows affected (0.01 sec)
    
    MariaDB [sometest]> insert into self values ('', '', 'high level 1');
    Query OK, 1 row affected, 2 warnings (0.00 sec)
    
    MariaDB [sometest]> insert into self values ('', '', 'high level 2');
    Query OK, 1 row affected, 2 warnings (0.00 sec)
    
    MariaDB [sometest]> select * from self;
    +----+-----------+--------------+
    | id | parent_id | lib          |
    +----+-----------+--------------+
    |  1 |         0 | high level 1 |
    |  2 |         0 | high level 2 |
    +----+-----------+--------------+
    2 rows in set (0.00 sec)
    
    MariaDB [sometest]> insert into self values ('', '1', 'sub level 1');
    Query OK, 1 row affected, 1 warning (0.00 sec)
    
    MariaDB [sometest]> insert into self values ('', '1', 'sub level 2');
    Query OK, 1 row affected, 1 warning (0.00 sec)
    
    MariaDB [sometest]> insert into self values ('', '1', 'sub level 3');
    Query OK, 1 row affected, 1 warning (0.00 sec)
    
    MariaDB [sometest]> select * from self where id=1 or parent_id = 1;
    +----+-----------+--------------+
    | id | parent_id | lib          |
    +----+-----------+--------------+
    |  1 |         0 | high level 1 |
    |  3 |         1 | sub level 1  |
    |  4 |         1 | sub level 2  |
    |  5 |         1 | sub level 3  |
    +----+-----------+--------------+
    4 rows in set (0.00 sec)
    

    这样,您可以解除 10 个限制,并拥有更灵活的搜索可能性。我的直觉猜测也是搜索会更快(你应该扩展这个简单的例子,至少在parent_id 上添加一个索引)。

    【讨论】:

    • 谢谢,是的,拥有超过 10 个子类别的问题是个问题,虽然对于这个版本来说这不是一个大问题,但感谢您的提示!
    猜你喜欢
    • 1970-01-01
    • 2013-01-11
    • 2013-06-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-31
    • 1970-01-01
    • 2019-07-01
    相关资源
    最近更新 更多