sql - SQL 可以对数字的重要部分进行排序吗?

标签 sql

我有一列国家拨号代码,我想将前缀过滤到最左边的拨号代码中

这是源列:

prefix
------
542
54299
374
37477
37493
37494
37498
37447
37455
3749
37410
297
29756
29759
29766
29769
29796
29799
29773
29774
297600
297622
247
61
61861
61862
61863

这是我想要的结果示例。 sql 可以轻松地做到这一点吗?如何或有更好的方法。请记住,大约有 30k 行

significant     prefix
----------------------
542             542
542             54299
374             374
374             37477
374             37493
374             37494
374             37498
374             37447
374             37455
374             3749
374             37410
297             297
297             29756
297             29759
297             29766
297             29769
297             29796
297             29799
297             29773
297             29774
297             297600
297             297622
247             247
61              61
61              61861
61              61862
61              61863

最佳答案

您可能想尝试以下方法(使用 MySQL 的 INSTR()LENGTH() 函数):

SELECT ( SELECT   prefix 
         FROM     numbers n2 
         WHERE    INSTR(n1.prefix, n2.prefix) = 1 
         ORDER BY LENGTH(n2.prefix) 
         LIMIT    1
       ) AS significant,
       n1.prefix
FROM   numbers n1;

查看 @onedaywhen's answer对于上述查询的 ANSI SQL 版本。

测试用例:

CREATE TABLE numbers (prefix int);

INSERT INTO numbers VALUES (542);
INSERT INTO numbers VALUES (54299);
INSERT INTO numbers VALUES (374);
INSERT INTO numbers VALUES (37477);
INSERT INTO numbers VALUES (37493);
INSERT INTO numbers VALUES (37494);
INSERT INTO numbers VALUES (37498);
INSERT INTO numbers VALUES (37447);
INSERT INTO numbers VALUES (37455);
INSERT INTO numbers VALUES (3749);
INSERT INTO numbers VALUES (37410);
INSERT INTO numbers VALUES (297);
INSERT INTO numbers VALUES (29756);
INSERT INTO numbers VALUES (29759);
INSERT INTO numbers VALUES (29766);
INSERT INTO numbers VALUES (29769);
INSERT INTO numbers VALUES (29796);
INSERT INTO numbers VALUES (29799);
INSERT INTO numbers VALUES (29773);
INSERT INTO numbers VALUES (29774);
INSERT INTO numbers VALUES (297600);
INSERT INTO numbers VALUES (297622);
INSERT INTO numbers VALUES (247);
INSERT INTO numbers VALUES (61);
INSERT INTO numbers VALUES (61861);
INSERT INTO numbers VALUES (61862);
INSERT INTO numbers VALUES (61863);

结果:

+-------------+--------+
| significant | prefix |
+-------------+--------+
|         542 |    542 |
|         542 |  54299 |
|         374 |    374 |
|         374 |  37477 |
|         374 |  37493 |
|         374 |  37494 |
|         374 |  37498 |
|         374 |  37447 |
|         374 |  37455 |
|         374 |   3749 |
|         374 |  37410 |
|         297 |    297 |
|         297 |  29756 |
|         297 |  29759 |
|         297 |  29766 |
|         297 |  29769 |
|         297 |  29796 |
|         297 |  29799 |
|         297 |  29773 |
|         297 |  29774 |
|         297 | 297600 |
|         297 | 297622 |
|         247 |    247 |
|          61 |     61 |
|          61 |  61861 |
|          61 |  61862 |
|          61 |  61863 |
+-------------+--------+
27 rows in set (0.00 sec)

即使您使用 varchar 来存储数字,它也应该可以工作。


更新:

至于性能,您可能需要考虑缓存表中的重要部分:

CREATE TABLE numbers (prefix int, significant int);

-- Fill in the prefixes, leaving the significant field as NULL.

然后您可以按如下方式生成significant 字段(使用 MySQL):

UPDATE numbers n
JOIN   ( SELECT ( SELECT   prefix 
                  FROM     numbers n2 
                  WHERE    INSTR(n1.prefix, n2.prefix) = 1 
                  ORDER BY LENGTH(n2.prefix) 
                  LIMIT    1
                ) AS significant,
                n1.prefix
         FROM   numbers n1
       ) s ON (s.prefix = n.prefix)
SET    n.significant = s.significant;

SELECT * FROM numbers;
+--------+-------------+
| prefix | significant |
+--------+-------------+
|    542 |         542 |
|  54299 |         542 |
|    374 |         374 |
|  37477 |         374 |
|  37493 |         374 |
|  37494 |         374 |

...

每当您在 numbers 表中添加新行时,您可能希望运行 UPDATE 查询。

关于sql - SQL 可以对数字的重要部分进行排序吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3100356/

相关文章:

用于搜索具有特定标签的项目的 MySQL 查询

mysql - 如果查询有 1 行,则返回一个值,否则返回另一个值

mysql - SQL检查A和B是否IN(...)

php - 无法找出正确的sql查询

mysql 的 tinyints 总和

sql - postgres 选择聚合时间跨度

sql - Postgresql 查询 - 按子查询结果排序

sql - WHERE 强制转换列名等于

mysql - 简单的子查询会在巨大的表上减慢速度

sql - PostgreSQL - 从 LIMIT OFFSET 重复行