Как разбить каждую цифру числа на разные строки

Я хочу, чтобы что-то вроде SELECT splitDigits(123456789) as digits возвращалось:

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

Что мне действительно нужно

Я пытаюсь создать это подтверждение (идентификатор RUC Перу) в хранимой процедуре: Как разбить каждую цифру числа на разные строки

Я пытаюсь избежать циклов, поэтому я застрял на первом шаге, который заключается в том, чтобы взять первые 10 цифр и умножить каждую цифру на фиксированный скаляр, который зависит от позиции, а затем я должен суммировать все эти умножения.

Это в основном векторное умножение, и я пытаюсь построить вектор из первых 10 цифр 11-значного числа.

изображение не совсем понятно, как вам нужно его использовать .. вы должны лучше объяснить алгоритм.

Raymond Nijland 27.05.2019 19:04

@RaymondNijland На изображении стрелки сверху вниз означают умножение на цифры, скаляры ( 5 4 3 2 7 6 5 4 3 2 ) фиксированы

Madacol 27.05.2019 19:10

@RaymondNijland Тогда мне нужно суммировать все умножения. После этого есть некоторые тривиальные вычисления с результатом суммы, применяя некоторые модули и дополнения, но это выходит за рамки этого вопроса.

Madacol 27.05.2019 19:20
«Тогда я должен просуммировать все умножения». Более или менее похоже на это, я действительно не был уверен, что означает % на изображении..
Raymond Nijland 27.05.2019 19:27

Проверьте мой ответ .. я предполагаю, что окончательный результат должен быть 8 ..

Raymond Nijland 27.05.2019 19:32

Я откатил вашу правку. Решения никогда относятся к вопросу. Если вы хотите опубликовать ответ, обобщающий решения, это нормально, но убедитесь, что ответ действительно добавляет что-то новое в сообщение. Простое краткое изложение того, что уже есть на странице, бесполезно. Кто-то может просто прочитать ответы.

Cody Gray 28.05.2019 19:37
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
В последние годы архитектура микросервисов приобрела популярность как способ построения масштабируемых и гибких приложений. Laravel , популярный PHP...
Как построить CRUD-приложение в Laravel
Как построить CRUD-приложение в Laravel
Laravel - это популярный PHP-фреймворк, который позволяет быстро и легко создавать веб-приложения. Одной из наиболее распространенных задач в...
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
Освоение PHP и управление базами данных: Создание собственной СУБД - часть II
В предыдущем посте мы создали функциональность вставки и чтения для нашей динамической СУБД. В этом посте мы собираемся реализовать функции обновления...
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
Роли и разрешения пользователей без пакета Laravel 9
Роли и разрешения пользователей без пакета Laravel 9
Этот пост изначально был опубликован на techsolutionstuff.com .
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
Как установить LAMP Stack - Security 5/5 на виртуальную машину Azure Linux VM
В предыдущей статье мы завершили установку базы данных, для тех, кто не знает.
0
6
88
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

Ответ принят как подходящий
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
;

Then I have to sum all the multiplications. After that there's some trivial calculations with the result of the sum, applying some modulus and complements, but it's out of the scope of this question.

Почему за рамками этого вопроса, ведь мы любим решать эти вопросы.

Запрос

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                                                  |

См. демо

Если также следует использовать модуль 10, что, как я предполагаю, должно быть
((11 - (SUM(vector_input.vector_input__summed) % 11)) % 10) см. демо

Поскольку формат числа фиксирован, вам просто нужна базовая математика:

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

Использование ответов Наэ и Рэймонда

Чтобы разбить число фиксированной длины на отдельные строки

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

Количество символов переменной длины см. в ответе Наэ.


Вся проверка 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

Другие вопросы по теме