验证帐户号SQL表

验证帐户号SQL表,sql,postgresql,Sql,Postgresql,我希望使用以下规则从表中选择数据,但在编写查询时遇到问题。我正在使用PostgreSQL,无法创建自定义项。该表如下所示: id | user_id | account_number ------------------------------- 1 | 1 | 12345671 2 | 4 | 12356673 3 | 7 | 12325678 SELECT * FROM table_name WHERE account_numb

我希望使用以下规则从表中选择数据,但在编写查询时遇到问题。我正在使用PostgreSQL,无法创建自定义项。该表如下所示:

id  | user_id  | account_number
-------------------------------
 1  |    1     | 12345671
 2  |    4     | 12356673
 3  |    7     | 12325678
SELECT * FROM table_name WHERE
  account_number SIMILAR TO '[0-9]{8}'
  AND (
    1 * CAST(SUBSTR(account_number, 1, 1) AS INTEGER) +
    2 * CAST(SUBSTR(account_number, 2, 1) AS INTEGER) +
    3 * CAST(SUBSTR(account_number, 3, 1) AS INTEGER) +
    1 * CAST(SUBSTR(account_number, 4, 1) AS INTEGER) +
    2 * CAST(SUBSTR(account_number, 5, 1) AS INTEGER) +
    3 * CAST(SUBSTR(account_number, 6, 1) AS INTEGER) +
    1 * CAST(SUBSTR(account_number, 7, 1) AS INTEGER)
  )%10 = CAST(SUBSTR(account_number, 8, 1) AS INTEGER)
id和用户id是整数,而帐号是字符串。我想选择符合以下条件的帐号:

  • 帐号字符串正好包含8位数字
  • 验证方案
  • 取前7位数字
  • 将第一个数字乘以1,第二个数字乘以2,第三个数字乘以3,第四个数字乘以1,第五个数字乘以2,第六个数字乘以3,第七个数字乘以1
  • 将每个数字乘以相关数字的结果求和
  • 如果第8位数字与mod(总和,10)相同,则选择此数字
在上面的这个表中,我应该只返回查询的前两行

重复一次,我无法创建UDF,所以我想知道在查询中使用普通SQL是否可行


谢谢

是的,你能做到。基本上,使用“类似于”检查精确的8位数字,然后使用子字符串和cast进行计算。大概是这样的:

id  | user_id  | account_number
-------------------------------
 1  |    1     | 12345671
 2  |    4     | 12356673
 3  |    7     | 12325678
SELECT * FROM table_name WHERE
  account_number SIMILAR TO '[0-9]{8}'
  AND (
    1 * CAST(SUBSTR(account_number, 1, 1) AS INTEGER) +
    2 * CAST(SUBSTR(account_number, 2, 1) AS INTEGER) +
    3 * CAST(SUBSTR(account_number, 3, 1) AS INTEGER) +
    1 * CAST(SUBSTR(account_number, 4, 1) AS INTEGER) +
    2 * CAST(SUBSTR(account_number, 5, 1) AS INTEGER) +
    3 * CAST(SUBSTR(account_number, 6, 1) AS INTEGER) +
    1 * CAST(SUBSTR(account_number, 7, 1) AS INTEGER)
  )%10 = CAST(SUBSTR(account_number, 8, 1) AS INTEGER)
当然,在您的示例中,这不会返回任何行,因为:

1×1 + 2×2 + 3x3 + 1×4 + 2×5 + 3×6 + 1×7 = 53
53 MOD 10 = 3
3 ≠ 1

PS:您确实意识到UDF可以用C以外的语言编写。例如,您可以用PL/pgSQL编写一个UDF。

只需创建一个表格,在其中拆分您的数字,然后进行算术运算(当然,您可以在
..
的位置填写其余内容)

当然,如果您不想创建一个单独的表,那么始终可以将用于创建
digits
表的
select
语句放入第二个查询的子查询中

select id, 
       user_id,
       digit_sum, 
       last_digit 
from (
  select id, 
         user_id,
         (substring(account_number,1,1)::int + 
          substring(account_number,2,1)::int * 2 + 
          substring(account_number,3,1)::int * 3 + 
          substring(account_number,4,1)::int + 
          substring(account_number,5,1)::int * 2 + 
          substring(account_number,6,1)::int * 3 +
          substring(account_number,7,1)::int ) as digit_sum, 
          substring(account_number,8,1)::int as last_digit
  from accounts
) t
where last_digit = digit_sum % 10

为了让生活更轻松,我将创建一个视图,对值进行拆分和求和。然后,您只需要从该视图中选择我用于派生表的where条件。

您可以尝试以下方法

select *,   (
    (substring(account_number from 1 for 1)::integer * 1) +
    (substring(account_number from 2 for 1)::integer * 2) +
    (substring(account_number from 3 for 1)::integer * 3) +
    (substring(account_number from 4 for 1)::integer * 1) +
    (substring(account_number from 5 for 1)::integer * 2) +
    (substring(account_number from 6 for 1)::integer * 3) +
    (substring(account_number from 7 for 1)::integer * 1)
   ) as sums,
  (
    (substring(account_number from 1 for 1)::integer * 1) +
    (substring(account_number from 2 for 1)::integer * 2) +
    (substring(account_number from 3 for 1)::integer * 3) +
    (substring(account_number from 4 for 1)::integer * 1) +
    (substring(account_number from 5 for 1)::integer * 2) +
    (substring(account_number from 6 for 1)::integer * 3) +
    (substring(account_number from 7 for 1)::integer * 1)
   ) % 10 as mod_10
from acct_no
where length(account_number) = 8 

我将计算结果写入SELECT子句而不是WHERE子句,因为要么我的算术错误,要么您的规格错误。

对于id=1的行,总和为'1+2*2+3*3+4+5*2+6*3+7=53,这将为mod(53,10)生成3。所以我不明白为什么该行应该返回,因为最后一位数字是1,而不是3UDF应该代表用户定义的函数或用户定义的字段?