【发布时间】:2021-04-10 10:02:53
【问题描述】:
我首先使用 MS SQL 来确定如何将标签对齐在一起。
如果您想重新创建未规范化的表,这里是架构。
CREATE TABLE unnormalized(
vendor_tag varchar(200),
vendor_tag_name varchar(200),
vendor_id int
);
INSERT INTO unnormalized
VALUES
('5,8,30,24','Burgers,Desserts,Fries,Salads',1),
('5','Burgers',2),
('8,42','Desserts,Mexican',3),
('1,5,30,16','American,Burgers,Fries,Sandwiches',4),
('1,5,30,16','American,Burgers,Fries,Sandwiches',5);
这是规范化表的代码
SELECT
--*
DISTINCT CAST(tag_id AS INT) as tag_id ,tag_name
FROM unnormalized
CROSS APPLY
(
(SELECT
value as tag_id,
ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS rn
FROM STRING_SPLIT(vendor_tag,',')
) a1
INNER JOIN
(SELECT
value as tag_name,
ROW_NUMBER() OVER(ORDER BY (SELECT NULL)) AS rn
FROM STRING_SPLIT(vendor_tag_name,',')
) a2
ON a1.rn = a2.rn
)
ORDER BY tag_id
现在我正在尝试使用 SQLite 重写此代码。但是,SQLite 中没有一些差异,例如“CROSS APPLY”和“STRING_SPLIT”。我环顾四周,发现 CROSS APPLY 可能类似于 SQLite 中的“CROSS JOIN”,并且可能使用类似这样的东西在它找到的第一个逗号处分隔字符串??
WITH split(vendor_id, vendor_tag, str) AS (
SELECT vendor_id, '', vendor_tag||',' FROM unnormalized
UNION ALL SELECT vendor_id,
substr(str, 0, instr(str, ',')),
substr(str, instr(str, ',')+1)
FROM split
WHERE str
)
SELECT vendor_id, vendor_tag
FROM split
WHERE vendor_tag
ORDER BY vendor_id;
【问题讨论】:
-
修复你的数据模型!不要在单个列中存储多个值!不要将数字存储为字符串!
-
这个表不只是“未标准化”,它违反了最基本的设计规则——每个单元格都应该包含一个 atomic 值。如果您使用正确的模式,您将不会有任何问题。即使在具有数组的数据库中,不同数组的元素之间也没有关系
-
对于 SQLite,通过拆分 SQL 中的值,您将一无所获。 SQLite 是一个嵌入式 数据库,这意味着引擎由您的应用程序托管和运行,使用您的应用程序的 RAM。使用客户端应用程序的语言拆分字符串比尝试在 SQLite 中执行相同操作要快得多
-
@Panagiotis Kanavos 该表是我在 kaggle 中找到的 csv 文件中的数据,并且正在做一些练习以将数据填充到数据库中
-
你为什么使用这样的模式?你试图解决什么问题?不是速度或可扩展性——这个模式非常慢,根本无法扩展。每个查询都必须扫描整个表,并且不能使用任何索引。空间?这可能比具有整数 ID 的适当表使用 更多 空间,即使对于少数供应商也是如此。如果你有很多供应商,你可以在 SQL Server 中使用表压缩
标签: sql sql-server sqlite