Plsql 将十进制转换为三个堆栈

Plsql 将十进制转换为三个堆栈,plsql,scripting,Plsql,Scripting,我正在尝试使用下一个逻辑或类似的东西将十进制数转换为,呃,三个堆栈,但我无法获得严格的alogrythm: 1 0 0 1 2 0 1 0 3 0 1 1 4 1 0 0 5 1 0 1 6 1 1 0 7 1 1 1 8 0 0 2 9 0 2 0 10 0 2 1 11 2 0

我正在尝试使用下一个逻辑或类似的东西将十进制数转换为,呃,三个堆栈,但我无法获得严格的alogrythm:

1       0   0   1
2       0   1   0
3       0   1   1
4       1   0   0
5       1   0   1
6       1   1   0
7       1   1   1
8       0   0   2
9       0   2   0
10      0   2   1
11      2   0   0
12      1   0   2
13      1   1   2
14      1   2   1
15      2   0   1
16      2   1   0
17      2   1   1
18      2   1   2
第一个建议是使用两个内部循环,一个用于减少输入小数,第二个用于在堆栈之间切换

在pl sql中进行了可怕的半尝试,它正在反向工作:

declare
type arr_type is table of varchar(32) index by binary_integer;
arr arr_type;
i number := 12;
z number := 0;
x number := 0;
c number := 0;
gg number;
begin
  arr(1) := 'z';
  arr(2) := 'x';
  arr(3) := 'c';
  gg := 0; -- array position
  i  := i + 1;  -- 
    loop
    i  := i - 1;
    gg := gg + 1;
      if arr(gg) = 'z' 
        then 
          z := z + 1;
          --if c > 0 then c := c - 1; end if;
      elsif arr(gg) = 'x'
        then 
          x := x + 1;
          --if z > 0 then z := z - 1; end if;
      elsif arr(gg) = 'c'
        then 
          c := c + 1;
          --if x > 0 then x := x - 1; end if;
      end if;
      --
      if gg = 3 then gg := 0;
      end if;
    if i = 1 then exit; end if;
    dbms_output.put_line(z || ' ' || x || ' ' || c);
    end loop;
end;

谢谢。

这里有一种方法是一致的和向后兼容的,而且它可以在一个SQL语句中完成:

WITH sample_data AS (SELECT LEVEL ID FROM dual CONNECT BY LEVEL <= 16)
SELECT id,
       FLOOR(ID/4) "2^2",
       4*FLOOR(ID/4),
       ID - 4*FLOOR(ID/4),
       floor((ID - 4*FLOOR(ID/4))/2) "2^1",

       ID - 2*(floor((ID - FLOOR(ID/4))/2)) "2^0"
FROM   sample_data;

WITH sample_data AS (SELECT LEVEL ID FROM dual CONNECT BY LEVEL <= 16)
-- end of generating sample data for the below query to work on
SELECT id,
       FLOOR(ID/4) "2^2",
       FLOOR( (ID - 4*FLOOR(ID/4)) /2) "2^1",
       ID - 4*FLOOR(ID/4) - 2*FLOOR( (ID - 4*FLOOR(ID/4)) /2) "2^0"
FROM   sample_data;

        ID        2^2        2^1        2^0
---------- ---------- ---------- ----------
         1          0          0          1
         2          0          1          0
         3          0          1          1
         4          1          0          0
         5          1          0          1
         6          1          1          0
         7          1          1          1
         8          2          0          0
         9          2          0          1
        10          2          1          0
        11          2          1          1
        12          3          0          0
        13          3          0          1
        14          3          1          0
        15          3          1          1
        16          4          0          0
ETA:这里有一种方法,可以将ids=1到7的模式的结果简单地添加到第n-1个模式中,例如,对于id=8,模式与id=1 col1=col2=col3-1相同,但在每列中加上1,id=15是相同的模式,这是第三次:

WITH sample_data AS (SELECT LEVEL -1 ID FROM dual CONNECT BY LEVEL <= 21)
SELECT ID,
       col1,
       col2,
       col3,
       col1 * 4 + col2 * 2 + col3 check_col
FROM   (SELECT ID,
               floor((ID-1)/7) + CASE WHEN MOD(ID, 7) IN (1,2,3) THEN 0
                                 --     WHEN ID = 0 THEN 1
                                  ELSE 1
                             END col1,
               FLOOR((ID-1)/7) + CASE WHEN MOD(ID, 7) IN (1,4,5) THEN 0
                                  --    WHEN ID = 0 THEN 1
                                  ELSE 1
                                 END col2,
               FLOOR((ID-1)/7) + CASE WHEN MOD(ID, 7) IN (2,4,6) THEN 0
                          ELSE 1
                     END col3
        FROM   sample_data) "MAIN";

        ID       COL1       COL2       COL3  CHECK_COL
---------- ---------- ---------- ---------- ----------
         0          0          0          0          0
         1          0          0          1          1
         2          0          1          0          2
         3          0          1          1          3
         4          1          0          0          4
         5          1          0          1          5
         6          1          1          0          6
         7          1          1          1          7
         8          1          1          2          8
         9          1          2          1          9
        10          1          2          2         10
        11          2          1          1         11
        12          2          1          2         12
        13          2          2          1         13
        14          2          2          2         14
        15          2          2          3         15
        16          2          3          2         16
        17          2          3          3         17
        18          3          2          2         18
        19          3          2          3         19
        20          3          3          2         20
我只将外部查询放在主查询周围,以证明列值在check\u col中返回正确答案;您不一定需要外部查询


注意,我假设你只想要正整数;我不想说负整数会发生什么。

将数字分成三部分的逻辑是什么?它一开始看起来非常像二进制,但后来我们找到了8,变成了0,0,2。为什么不是1,1,2?这三列代表什么?8看起来很糟糕,因为我没有第四列和第四列,所以我需要分成三部分。事实上,8可以是1,1,2,但它会打破顺序。好的,但是为什么它是0,0,2的逻辑是什么?我们是不是应该能够获取这三列并从中重构相应的十进制值?@Boneist,是的,我希望能够双向转换。0,0,2作为下一个序列值对我来说很自然。比如使用下一个秩。那么为什么1=0,0,1而2=0,1,0和8=0,0,2呢?如果列以二进制形式表示2^2、2^1、2^0,那么8将是0、0、8或1、1、2。你为什么要把这些值分成三列呢?这背后的目的是什么?我已经更新了我的答案,加入了一个方法,可以更均匀地在列之间共享值。谢谢,这绝对是我所期望的。感谢你的帮助和时间。
WITH sample_data AS (SELECT LEVEL -1 ID FROM dual CONNECT BY LEVEL <= 21)
SELECT ID,
       col1,
       col2,
       col3,
       col1 * 4 + col2 * 2 + col3 check_col
FROM   (SELECT ID,
               floor((ID-1)/7) + CASE WHEN MOD(ID, 7) IN (1,2,3) THEN 0
                                 --     WHEN ID = 0 THEN 1
                                  ELSE 1
                             END col1,
               FLOOR((ID-1)/7) + CASE WHEN MOD(ID, 7) IN (1,4,5) THEN 0
                                  --    WHEN ID = 0 THEN 1
                                  ELSE 1
                                 END col2,
               FLOOR((ID-1)/7) + CASE WHEN MOD(ID, 7) IN (2,4,6) THEN 0
                          ELSE 1
                     END col3
        FROM   sample_data) "MAIN";

        ID       COL1       COL2       COL3  CHECK_COL
---------- ---------- ---------- ---------- ----------
         0          0          0          0          0
         1          0          0          1          1
         2          0          1          0          2
         3          0          1          1          3
         4          1          0          0          4
         5          1          0          1          5
         6          1          1          0          6
         7          1          1          1          7
         8          1          1          2          8
         9          1          2          1          9
        10          1          2          2         10
        11          2          1          1         11
        12          2          1          2         12
        13          2          2          1         13
        14          2          2          2         14
        15          2          2          3         15
        16          2          3          2         16
        17          2          3          3         17
        18          3          2          2         18
        19          3          2          3         19
        20          3          3          2         20