【问题标题】:sql query for finding prime numbers用于查找素数的sql查询
【发布时间】:2017-01-14 16:47:09
【问题描述】:

假设我的表格中有 1 到 100 之间的数字。 我需要编写一个查询来从该表中提取所有素数。如何在不使用任何类型的过程或循环的情况下通过非常基本和简单的查询来实现这一点。

【问题讨论】:

  • 我认为你不能得到这样的查询
  • 详细解释您的问题
  • 通过 sql 查询来实现这一点,您需要有另一个表,其中所有除数的数字/2 或平方根(数字)都驻留。
  • 可能重复link
  • 如果你知道怎么做,请告诉我,以便我删除我的网上银行帐户。

标签: mysql primes


【解决方案1】:

选择 MyISAM 是有原因的。我将在 cmets 中解释。主要是为了保证在自插入期间没有 innodb 间隙异常(从而丢弃 id)。不要过多地研究它的模式部分。我只需要生成一个表1到100。

对于 MyISAM,它不会受到 INNODB 间隙异常 ref1 ref2 的影响,并且它保证在自插入和 INNODB 间隙范围内不会出现从 1 到 100 的间隙。

无论如何,如果你提供了实际的表格,我就不需要提及了。或者ALTER TABLE 可以在数据加载后更改引擎。

架构

create table nums
(   id int auto_increment primary key,
    thing char(1) null
)ENGINE=MyISAM;

insert nums(thing) values(null),(null),(null),(null),(null),(null),(null);
insert nums(thing) select thing from nums;
insert nums(thing) select thing from nums;
insert nums(thing) select thing from nums;
insert nums(thing) select thing from nums;
select count(*) from nums; -- 112
delete from nums where id>100;
select min(id),max(id),count(*) from nums;
-- 1 100 100

查询

select id from nums where id>1 and id not in 
(   select distinct n2id 
    from 
    (   select n1.id as n1id, n2.id as n2id 
        from nums n1 
        cross join nums n2 
        where n1.id<(n2.id) and n1.id>1 and (n2.id MOD n1.id = 0) 
    ) xDerived 
) 
order by id; 

结果

+----+
| id |
+----+
|  2 |
|  3 |
|  5 |
|  7 |
| 11 |
| 13 |
| 17 |
| 19 |
| 23 |
| 29 |
| 31 |
| 37 |
| 41 |
| 43 |
| 47 |
| 53 |
| 59 |
| 61 |
| 67 |
| 71 |
| 73 |
| 79 |
| 83 |
| 89 |
| 97 |
+----+
25 rows in set (0.00 sec)

注意,上面的 ref2 是一个夸张的“快速创建 4.7M 行表”,如果不这样做肯定会造成 INNODB id 间隙。这只是该引擎的一个已知事实。

【讨论】:

    【解决方案2】:
    SET @potential_prime = 1;
    SET @divisor = 1;
    
    SELECT GROUP_CONCAT(POTENTIAL_PRIME SEPARATOR ',') FROM
        (SELECT @potential_prime := @potential_prime + 1 AS POTENTIAL_PRIME FROM
        information_schema.tables t1,
        information_schema.tables t2
        LIMIT 1000) list_of_potential_primes
    WHERE NOT EXISTS(
        SELECT * FROM
            (SELECT @divisor := @divisor + 1 AS DIVISOR FROM
            information_schema.tables t4,
            information_schema.tables t5
            LIMIT 1000) list_of_divisors
        WHERE MOD(POTENTIAL_PRIME, DIVISOR) = 0 AND POTENTIAL_PRIME <> DIVISOR);
    

    【讨论】:

      猜你喜欢
      • 2016-05-28
      • 1970-01-01
      • 1970-01-01
      • 2021-11-15
      • 1970-01-01
      • 2011-07-29
      • 1970-01-01
      • 2017-07-29
      • 2021-02-09
      相关资源
      最近更新 更多