如何将数字的每个数字分成不同的行

时间:2019-05-27 16:50:51

标签: mysql sql numbers

我想要类似SELECT splitDigits(123456789) as digits的东西返回:

 digits 
-------
  1
  2
  3
  4
  5
  6
  7
  8
  9

我真正需要的东西

我正在尝试在存储过程中制作this validation(秘鲁的RUC ID):

我试图避免循环,所以我陷入了第一步,即获取前10位数字,并将每位数字乘以取决于位置的固定标量,然后我必须对所有这些乘法求和

基本上是向量乘法,我正在尝试从11位数字的前10位构造一个向量。

4 个答案:

答案 0 :(得分:2)

由于数字的格式是固定的,因此您只需要一些基本的数学运算即可:

SELECT num div          10 % 10 * 2
     + num div         100 % 10 * 3
     + num div        1000 % 10 * 4
     + num div       10000 % 10 * 5
     + num div      100000 % 10 * 6
     + num div     1000000 % 10 * 7
     + num div    10000000 % 10 * 2
     + num div   100000000 % 10 * 3
     + num div  1000000000 % 10 * 4
     + num div 10000000000 % 10 * 5 AS s
FROM (
    SELECT 20503644968 AS num
) AS t
-- 157

答案 1 :(得分:1)

SELECT
    SUBSTR(3987654321, idx, 1) AS SplitDigits,
    3 * (SUBSTR(3987654321, idx, 1)) AS ConstTimesSplitDigits
   -- SUM(SUBSTR(2050364496, idx, 1) * (SUBSTR(5432765432, idx, 1))) AS Result
FROM (SELECT @cnt := 0) A
-- cross join any table has rows greater than or equal to your liking
CROSS JOIN (SELECT (@cnt := @cnt + 1) idx FROM INFORMATION_SCHEMA.TABLES LIMIT 10) B
;

答案 2 :(得分:1)

  

然后我必须对所有乘法求和。在那之后有一些   求和的结果的平凡计算,应用一些模数   和补充,但这不在此问题的范围内。

为什么我们喜欢解决这些问题,所以超出了这个问题的范围。

查询

SELECT 
 11 - (SUM(vector_input.vector_input__summed) % 11)
FROM (

SELECT 
 vector.item * input.item AS vector_input__summed

FROM (
 SELECT 
  DISTINCT
    SUBSTRING(5432765432, vector_number_generator.number, 1) AS item
    ,  vector_number_generator.number  AS position
FROM (
  SELECT 
   @vector_row := @vector_row + 1 AS number
  FROM (
    SELECT 0 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION   SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
  ) AS row_1
  CROSS JOIN (
    SELECT @vector_row := 0 
  ) AS init_user_params 
) AS vector_number_generator

) AS vector
INNER JOIN (
  SELECT 
  DISTINCT
       SUBSTRING(2050364496, number_generator.number, 1) AS item
    ,  number_generator.number  AS position
FROM (
  SELECT 
   @row := @row + 1 AS number
  FROM (
    SELECT 0 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION   SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
  ) row1
  CROSS JOIN (
    SELECT 0 UNION SELECT 1 UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION  SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9
  ) row2
  CROSS JOIN (
    SELECT @row := 0 
  ) AS init_user_params 
) AS number_generator
) AS input
ON
 vector.position = input.position
) AS vector_input

结果

| 11 - (SUM(vector_input.vector_input__summed) % 11) |
| -------------------------------------------------- |
| 8                                                  |

请参见demo

如果还应该使用模数10,我认为应该是
((11 - (SUM(vector_input.vector_input__summed) % 11)) % 10)参见demo

答案 3 :(得分:0)

使用Nae'sRaymond's答案

要将固定长度的数字拆分为单独的行

SELECT
   SUBSTR(1234567890123, range10, 1)
FROM (
  SELECT 1 range10
  UNION SELECT 2
  UNION SELECT 3
  UNION SELECT 4
  UNION SELECT 5
  UNION SELECT 6
  UNION SELECT 7
  UNION SELECT 8
  UNION SELECT 9
  UNION SELECT 10
  UNION SELECT 11
  UNION SELECT 12
  UNION SELECT 13
) A

有关可变长度的字符,请参见Nae's答案


整个RUC的验证都变成一个函数

CREATE FUNCTION `validate_ruc`(`ruc` BIGINT) RETURNS binary(1)
BEGIN
DECLARE isValid BINARY;

IF LENGTH(ruc) != 11 THEN RETURN FALSE; END IF;

SELECT
  ((11 - (sum % 11)) % 10) = (ruc % 10)
INTO isValid
FROM (
  SELECT
     SUM( SUBSTR(ruc, range10, 1) * (SUBSTR(5432765432, range10, 1)) ) AS sum
  FROM (
    SELECT 1 range10
    UNION SELECT 2
    UNION SELECT 3
    UNION SELECT 4
    UNION SELECT 5
    UNION SELECT 6
    UNION SELECT 7
    UNION SELECT 8
    UNION SELECT 9
    UNION SELECT 10
  ) A
) B;

RETURN isValid;

END