【问题标题】:Is there a way to load multiple values of one column into new lines to a single row in sql有没有办法将一列的多个值加载到sql中的单行的新行中
【发布时间】:2020-09-07 13:19:55
【问题描述】:

这就是我的数据的样子,

emp_id,skills
1234,python|java|sql|R|javascript
5639,C|HTML|php|perl

这就是需要将数据加载到表中的方式

emp_id  skills
        
       python
1234    java
        sql
        R
        perl

        C
5639    HTML
        php

其实我已经换了|使用 \n 但它没有被加载到下一行,而只是通过添加空格来加载。 我将使用 python etl 将数据加载到表中,所以即使是后处理我也可以添加。 有什么建议吗??

【问题讨论】:

  • 用您正在使用的数据库标记您的问题。然后,修复您的数据模型。不要在一个字符串中存储多个值。您可以使用 JSON,但正确的关系模型将使用联结表。
  • Gordon,你认为任何后期处理对 python 有帮助吗?
  • 。 .不,我认为 SQL 中适当的数据模型会有所帮助。我对 Python 中发生的事情不太敏感。

标签: python sql sql-insert


【解决方案1】:

这是关系数据库的行为,不能只在每个组中显示一次 emp_id 并将其所有元素显示为每行一个。改变这种显示数据的方式是前端的特权和责任,而不是数据库的。所以在 Python 中这样做。

话虽如此,Impala 有 SPLIT_PART() 字符串函数,它返回由您作为参数传递的分隔符分隔的字符串的第 n 个标记。

因此,与一系列连续整数交叉连接,然后应用 SPLIT_PART(skills,'|',i) 即可满足您的需求。

实际上,以我(从不)的拙见,每当有人向您抛出格式如此不愉快的文件以加载到数据库中时,您都应该这样做。始终使用以下技术垂直化逗号/条形/分号/或_whatever分隔的“值”列表,并垂直存储数据。:

WITH
-- your input
input( emp_id,skills) AS (
          SELECT 1234,'python|java|sql|R|javascript'
UNION ALL SELECT 5639,'C|HTML|php|perl'
)
,
-- a big enough series of integers ..
i(i) AS (
          SELECT 1
UNION ALL SELECT 2
UNION ALL SELECT 3
UNION ALL SELECT 4
UNION ALL SELECT 5
UNION ALL SELECT 6
UNION ALL SELECT 7
UNION ALL SELECT 8
)
SELECT
  emp_id
, SPLIT_PART(skills,'|',i) AS skill
FROM input
CROSS JOIN i
WHERE SPLIT_PART(skills,'|',i) <> ''
ORDER BY 
  emp_id
, i
;
-- out  emp_id |   skill    
-- out --------+------------
-- out    1234 | python
-- out    1234 | java
-- out    1234 | sql
-- out    1234 | R
-- out    1234 | javascript
-- out    5639 | C
-- out    5639 | HTML
-- out    5639 | php
-- out    5639 | perl

使用两个条形/逗号分隔的列,它可能如下所示:

WITH
-- your input, enhanced
input( emp_id,skills,pubs) AS (
          SELECT 1234,'python|java|sql|R|javascript','ship inn,anchor,stag'
UNION ALL SELECT 5639,'C|HTML|php|perl'             ,'black horse,crown,mitre'
)
,
-- a big enough series of integers ..
i(i) AS (
          SELECT 1
UNION ALL SELECT 2
UNION ALL SELECT 3
UNION ALL SELECT 4
UNION ALL SELECT 5
UNION ALL SELECT 6
UNION ALL SELECT 7
UNION ALL SELECT 8
)
,
-- another big enough series of integers ..
j(j) AS (
  SELECT
    i AS j
  FROM i
)
SELECT
  emp_id
, i AS skill_sequence
, SPLIT_PART(skills,'|',i) AS skill
, j AS pub_sequence
, SPLIT_PART(pubs,',',j) AS pub
FROM input
CROSS JOIN i
CROSS JOIN j
WHERE SPLIT_PART(skills,'|',i) <> ''
  AND SPLIT_PART(pubs,  ',',j) <> ''
ORDER BY 
  emp_id
, i
, j
;
-- out  emp_id | skill_sequence |   skill    | pub_sequence |     pub     
-- out --------+----------------+------------+--------------+-------------
-- out    1234 |              1 | python     |            1 | ship inn
-- out    1234 |              1 | python     |            2 | anchor
-- out    1234 |              1 | python     |            3 | stag
-- out    1234 |              2 | java       |            1 | ship inn
-- out    1234 |              2 | java       |            2 | anchor
-- out    1234 |              2 | java       |            3 | stag
-- out    1234 |              3 | sql        |            1 | ship inn
-- out    1234 |              3 | sql        |            2 | anchor
-- out    1234 |              3 | sql        |            3 | stag
-- out    1234 |              4 | R          |            1 | ship inn
-- out    1234 |              4 | R          |            2 | anchor
-- out    1234 |              4 | R          |            3 | stag
-- out    1234 |              5 | javascript |            1 | ship inn
-- out    1234 |              5 | javascript |            2 | anchor
-- out    1234 |              5 | javascript |            3 | stag
-- out    5639 |              1 | C          |            1 | black horse
-- out    5639 |              1 | C          |            2 | crown
-- out    5639 |              1 | C          |            3 | mitre
-- out    5639 |              2 | HTML       |            1 | black horse
-- out    5639 |              2 | HTML       |            2 | crown
-- out    5639 |              2 | HTML       |            3 | mitre
-- out    5639 |              3 | php        |            1 | black horse
-- out    5639 |              3 | php        |            2 | crown
-- out    5639 |              3 | php        |            3 | mitre
-- out    5639 |              4 | perl       |            1 | black horse
-- out    5639 |              4 | perl       |            2 | crown
-- out    5639 |              4 | perl       |            3 | mitre

【讨论】:

  • 说我还有一个类似技能的专栏,我这样的情况下我该怎么办?
  • 我刚刚添加了一个新列:“pubs”,这次用逗号分隔。您需要第二个整数系列(我从i 中选择并将列重命名为j) - 并与该整数交叉连接。我将其添加到响应中。如果您的输入中有 3,4 个或更多这些野兽,则必须考虑为每个多值字符串创建一个单独的表:例如 CREATE TABLE skills (input_id INT FOREIGN KEY REFERENCES input, sequence INT, skill VARCHAR(32))
猜你喜欢
  • 1970-01-01
  • 2020-07-29
  • 1970-01-01
  • 2013-12-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-07
  • 2021-09-19
相关资源
最近更新 更多