Sqlite:根据非主键字段创建包含重复行的表

时间:2017-07-19 16:11:06

标签: sql sqlite

我有一个sqllite表;

CREATE TABLE tmp2(
  id INT,
  account TEXT,
  name TEXT,
)

我的表(表tmp2)看起来像:

 id  , account  , name

 1     A1        bob
 2     A2        dave,john,sally
 3     A3        tom

我需要创建一个新表(表B),这样只有一个名称/行:

 id  , account  , name

 1   A1        bob
 2   A2        dave
 2   A2        john
 2   A2        sally     
 3   A3        tom

复制所有其他字段。这是否可以使用sql,因为主键不能重复?还使用sql如何访问“dave,john,sally”中的各个名字?

2 个答案:

答案 0 :(得分:1)

更好的想法是实现两个这样的表

帐户持有人

Account  Account Holder(Foreign Key to Users.user_id)
 A1,      1
 A2,      2
 A2,      3
 A2,      4    
 A3,      5

用户

User_id     UserName
1        Bob
2        Dave
3        John
4        Sally
5        Tom

获得账户A2的所有持有人:

从user_id所在的用户中选择*(从Account_holders中选择Account_holder,其中Account ='A2')

答案 1 :(得分:1)

这是一个SQLite解决方案(基于MCVE,如本答案末尾所示)。

  • 制作递归公用表表达式with singles(id, account, first, rest) as
  • 来自UNION ALL
    • id,account和
    • 最初
      • tmp2,substr(name, 0, instr(name||', ', ', '))
      • 列表中的名字
      • tmp2中的其余列表,substr(name, instr(name||', ', ', ')+2)
    • 递归
      • 几乎一样,但来自CTE单曲
  • 来自该CTE的
  • 只需选择ID,帐户和名字select id, account, first from singles
  • 按ID排序并使用特殊分隔符匹配所需的输出,
    order by id.separator ' '
  • 附加'的一个小技巧,'第一;这使得一切模式重复1-N次

代码:

with singles(id, account, first, rest) as 
(    select id, 
            account,
            substr(name, 0, instr(name||', ', ', ')), 
            substr(name, instr(name||', ', ', ')+2) 
     from tmp2
 UNION
     select id, 
            account, 
            substr(rest, 0, instr(rest||', ', ', ')), 
            substr(rest, instr(rest||', ', ', ')+2) 
     from singles where rest!=''
) 
select id, account, first
from singles
order by id;

输出(.separator ' '):

1   A1   Bob
2   A2   dave
2   A2   john
2   A2   sally
3   A3   tom

MCVE(对不起小写的初始错别字......):

BEGIN TRANSACTION;
CREATE TABLE tmp2(
  id INT,
  account TEXT,
  name TEXT);
INSERT INTO tmp2 VALUES(1,'A1','Bob');
INSERT INTO tmp2 VALUES(2,'A2','dave, john, sally');
INSERT INTO tmp2 VALUES(3,'A3','tom');
COMMIT;

在Windows 10上使用SQLite 3.18.0 2017-03-28 18:48:43

如果您对使用SQLite的递归CTE感兴趣,我推荐这个,这是我对它们的了解: https://sqlite.org/lang_with.html

顺便说一句,我同意Joey Pinto,使用一个像样的数据库结构会更好......