使用SQL Server中的Division和Mod将列值转换为ASCII

发布于 2025-01-23 08:45:38 字数 1943 浏览 1 评论 0原文

我在SQL Server中有一个表,如下所示,如下面的许多列,

| D401                         | D402                         |
|------------------------------|------------------------------|
| 20808 8257 12339 12848 12345 | 20808 8257 1233 12848 12345  |
| 20808 8262 12849 14640 12852 | 20808 8262 12849 14640 12852 |

Requirement: Convert value ascii

例如python

  1. split d401列列值
df['D401'].str.split(pat="\t", expand=True).replace(r'\s+|\\n', ' ',regex=True).apply(pd.to_numeric)
  1. 转换为ASCII通过mod
  • 将每个拆分列除以256,而mod则按256
        # Apply mod function to each split column
        df['v0'] = df['v0'].apply(lambda x: chr(round(x / 256)) + chr(x % 256)).apply(lambda x: x[::-1])
        df['v1'] = df['v1'].apply(lambda x: chr(round(x / 256)) + chr(x % 256)).apply(lambda x: x[::-1])
        df['v2'] = df['v2'].apply(lambda x: chr(round(x / 256)) + chr(x % 256)).apply(lambda x: x[::-1])
        df['v3'] = df['v3'].apply(lambda x: chr(round(x / 256)) + chr(x % 256)).apply(lambda x: x[::-1])
        df['v4'] = df['v4'].apply(lambda x: chr(round(x / 256)) + chr(x % 256)).apply(lambda x: x[::-1])
     # after mod, join column

        df[D401] = df['v0'].astype(str) + df['v1'].astype(str) \
                + df['v2'].astype(str) + df['v3'].astype(str) \
                + df['v4'].astype(str)
     # drop old unnecessary split column
        df.drop(['v0', 'v1', 'v2', 'v3', 'v4'], axis=1, inplace=True)

ASCII输出

| D401       | D402       |
|------------|------------|
| HQA 300290 | HQA 300290 |
| HQF 120942 | HQF 120942 |

可以在SQL Server中使用相同的方法 当我

从SQL表中复制Notepad中的数据时,它终于有36个空间,

'20808 8257 12339 13616 13875                                    '

当我在Python中阅读时,它显示如下

'20808\t8257\t12339\t13616\t13875\r\n'

I have a table in SQL SERVER as below with many columns like below

| D401                         | D402                         |
|------------------------------|------------------------------|
| 20808 8257 12339 12848 12345 | 20808 8257 1233 12848 12345  |
| 20808 8262 12849 14640 12852 | 20808 8262 12849 14640 12852 |

Requirement: Convert value ascii

Example in python

  1. Split D401 column value
df['D401'].str.split(pat="\t", expand=True).replace(r'\s+|\\n', ' ',regex=True).apply(pd.to_numeric)
  1. Convert convert to ascii by mod
  • divide each split column by 256 and mod by 256
        # Apply mod function to each split column
        df['v0'] = df['v0'].apply(lambda x: chr(round(x / 256)) + chr(x % 256)).apply(lambda x: x[::-1])
        df['v1'] = df['v1'].apply(lambda x: chr(round(x / 256)) + chr(x % 256)).apply(lambda x: x[::-1])
        df['v2'] = df['v2'].apply(lambda x: chr(round(x / 256)) + chr(x % 256)).apply(lambda x: x[::-1])
        df['v3'] = df['v3'].apply(lambda x: chr(round(x / 256)) + chr(x % 256)).apply(lambda x: x[::-1])
        df['v4'] = df['v4'].apply(lambda x: chr(round(x / 256)) + chr(x % 256)).apply(lambda x: x[::-1])
     # after mod, join column

        df[D401] = df['v0'].astype(str) + df['v1'].astype(str) \
                + df['v2'].astype(str) + df['v3'].astype(str) \
                + df['v4'].astype(str)
     # drop old unnecessary split column
        df.drop(['v0', 'v1', 'v2', 'v3', 'v4'], axis=1, inplace=True)

Ascii Output

| D401       | D402       |
|------------|------------|
| HQA 300290 | HQA 300290 |
| HQF 120942 | HQF 120942 |

Is there a way to do the same in SQL SERVER itself

When i copy paste the data in notepad from sql table, it has 36 space at last

'20808 8257 12339 13616 13875                                    '

When i read it in Python it shows as below

'20808\t8257\t12339\t13616\t13875\r\n'

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

娇纵 2025-01-30 08:45:38

如您所述:使用部门和模量执行转换。之后,将其连接成一个字符串。

下面的解决方案将字符串分为行明智的明智,然后使用 string_agg() con缩

-- create sample table
create table tbl
(
    col varchar(100)
)
    
-- insert sample data
insert into tbl(col) values 
('20808 8257 12339 12848 12345'),
('20808 8262 12849 14640 12852');

-- change the space to tab delimiter
update tbl
set    col = replace(col, ' ', char(9));

-- define the delimiter : tab
declare @d char(1) = char(9);

-- using recursive cte to split the string on space
with cte as
(
     select org = col,
            n = 1,
            v = left(col, p - 1),
            col = substring(col, p + 1, len(col) - p.p)
     from   (
                select col = col + @d
                from   tbl 
            ) t
            cross apply
            (
                select p = case when charindex(@d, col) <> 0
                                then charindex(@d, col)
                                else len(col)
                                end
            ) p
            
     union all
            
     select org = org,
            n = n + 1,
            v = left(col, p.p - 1),
            col = substring(col, p.p + 1, len(col) - p.p)
     from   cte t
            cross apply
            (
                select p = case when charindex(@d, col) <> 0
                                then charindex(@d, col)
                                else len(col)
                                end
            ) p          
      where t.col <> ''
)
select org,
       string_agg(char(v % 256) + char(v / 256), '') within group (order by n)
from   cte
group by org

db&gt;

2列< /a>

更新:
更新了使用Tab定界符的两个小提琴,

我添加了另一个使用Jeff Moden的小提琴,该小提琴使用Jeff Moden的 delimitedsplit8k 。 delimitedsplit8k返回一个itemnumber。除非您正在使用Azure,否则string_split()不会返回string_agg()所需的顺序列。

As you have stated: use division and modulus to perform the conversion. After that concatenate into one string.

The solution below split the string into row wise and then use string_agg() to concatenate it

-- create sample table
create table tbl
(
    col varchar(100)
)
    
-- insert sample data
insert into tbl(col) values 
('20808 8257 12339 12848 12345'),
('20808 8262 12849 14640 12852');

-- change the space to tab delimiter
update tbl
set    col = replace(col, ' ', char(9));

-- define the delimiter : tab
declare @d char(1) = char(9);

-- using recursive cte to split the string on space
with cte as
(
     select org = col,
            n = 1,
            v = left(col, p - 1),
            col = substring(col, p + 1, len(col) - p.p)
     from   (
                select col = col + @d
                from   tbl 
            ) t
            cross apply
            (
                select p = case when charindex(@d, col) <> 0
                                then charindex(@d, col)
                                else len(col)
                                end
            ) p
            
     union all
            
     select org = org,
            n = n + 1,
            v = left(col, p.p - 1),
            col = substring(col, p.p + 1, len(col) - p.p)
     from   cte t
            cross apply
            (
                select p = case when charindex(@d, col) <> 0
                                then charindex(@d, col)
                                else len(col)
                                end
            ) p          
      where t.col <> ''
)
select org,
       string_agg(char(v % 256) + char(v / 256), '') within group (order by n)
from   cte
group by org

db<>fiddle demo

db<>fiddel demo for 2 columns

Updates:
Updated both fiddle to use tab delimiter

I have added another fiddle which uses Jeff Moden's DelimitedSplit8K. DelimitedSplit8K returns a ItemNumber. Unless you are working on Azure, the normal string_split() does not return an ordinal column which you required for the string_agg().

db<>fiddle demo using DelimitedSplit8K

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文