Sqlite:基于非主键字段创建具有重复行的表

Sqlite:基于非主键字段创建具有重复行的表,sql,sqlite,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

我有一个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中的各个名称?

更好的方法是实现两个类似这样的表

账户持有人

使用者

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


选择*from users where user\u id in Select Account\u holder from Account\u holder where Account='A2'

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

创建一个递归公共表表达式,其中singlesid、account、first和rest为 来自所有人的联盟 身份证、帐户和密码 开始 tmp2中列表中的第一个名称,子名称,0,instrname | |',',',' tmp2中列表的其余部分,子名称,instrname | |',','和'+2 递归地 基本相同,但来自CTE单曲 从这个CTE中,只需选择id、帐户和名字,然后选择id、帐户、单打第一名 按id排序并使用特殊分隔符匹配所需输出, 按id排序,.分隔符“” 先加上“,”的小技巧;这使得每样东西都是一个重复1-N次的单一图案 代码:

带.separator“”的输出:

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感兴趣,我建议您这样做,这是我对它们的知识来源:


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

只要主键不仅仅是id字段,当然。您可能会使主键成为id、account、name的复合键。一个更好的、基于模型的解决方案是将其分为两个表,一个表列出帐户,另一个表将名称与这些帐户联系起来。您的表似乎有两个职责。表tmp2和A是否相同?如果没有,请同时显示表A的结构。是的,修复了这个问题,对不起,这在任何脚本语言中都更容易做到。那么第二个和单个名称之间奇怪的空格/奇怪的空格数呢?你想要吗?或者,所有行中的名称都可以吗?谢谢Joey,在我的例子中,我处理的是一个遗留系统,它的数据采用表a的格式。我无法重新构造输入。因此,您正在寻找一个SQL查询来直接将表tmp2转换为表B?我不是SQL专家,但如果可能的话,可以。我很高兴,我一直想尝试使用递归CTE。@user61629我在答案中添加了我最喜欢的链接。
User_id     UserName
1        Bob
2        Dave
3        John
4        Sally
5        Tom
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;
1   A1   Bob
2   A2   dave
2   A2   john
2   A2   sally
3   A3   tom
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;