【发布时间】:2021-11-27 02:15:50
【问题描述】:
假设以下简单的scenario,其中一个产品行连接到一个主要类别、子类别和子子类别。
DECLARE @PRODUCTS TABLE (ID int, DESCRIPTION varchar(50), CAT varchar(30), SUBCAT varchar(30), SUBSUBCAT varchar(30));
INSERT @PRODUCTS (ID, DESCRIPTION, CAT, SUBCAT, SUBSUBCAT) VALUES
(1, 'NIKE MILLENIUM', '1', '10', '100'),
(2, 'NIKE CORTEZ', '1', '12', '104'),
(3, 'ADIDAS PANTS', '2', '27', '238'),
(4, 'PUMA REVOLUTION 5', '3', '35', '374'),
(5, 'SALOMON SHELTER CS', '4', '15', '135'),
(6, 'NIKE EBERNON LOW', '2', '14', '157');
DECLARE @CATS TABLE (ID int, DESCR varchar(100));
INSERT @CATS (ID, DESCR) VALUES
(1, 'MEN'),
(2, 'WOMEN'),
(3, 'UNISEX'),
(4, 'KIDS'),
(5, 'TEENS'),
(6, 'BACK TO SCHOOL');
DECLARE @SUBCATS TABLE (ID int, DESCR varchar(100));
INSERT @SUBCATS (ID, DESCR) VALUES
(10, 'FOOTWEAR'),
(12, 'OUTERWEAR'),
(14, 'SWIMWEAR'),
(15, 'HOODIES'),
(27, 'CLOTHING'),
(35, 'SPORTS');
DECLARE @SUBSUBCATS TABLE (ID int, DESCR varchar(100));
INSERT @SUBSUBCATS (ID, DESCR) VALUES
(100, 'RUNNING'),
(104, 'ZIP TOPS'),
(135, 'FLEECE'),
(157, 'BIKINIS'),
(238, 'PANTS'),
(374, 'JOGGERS');
SELECT prod.ID,
prod.DESCRIPTION,
CONCAT(cat1.DESCR, ' > ', cat2.DESCR, ' > ', cat3.DESCR) AS CATEGORIES
FROM @PRODUCTS AS prod
LEFT JOIN @CATS AS cat1 ON cat1.ID = prod.CAT
LEFT JOIN @SUBCATS AS cat2 ON cat2.ID = prod.SUBCAT
LEFT JOIN @SUBSUBCATS AS cat3 ON cat3.ID = prod.SUBSUBCAT;
现在假设@PRODUCTS 表上的外键不仅仅是它们各自表的索引。它们是多个类别、子类别和子子类别(如 here)的逗号分隔索引。
DECLARE @PRODUCTS TABLE (ID int, DESCRIPTION varchar(50), CAT varchar(30), SUBCAT varchar(30), SUBSUBCAT varchar(30));
INSERT @PRODUCTS (ID, DESCRIPTION, CAT, SUBCAT, SUBSUBCAT) VALUES
(1, 'NIKE MILLENIUM', '1, 2', '10, 12', '100, 135'),
(2, 'NIKE CORTEZ', '1, 5', '12, 15', '104, 374'),
(3, 'ADIDAS PANTS', '2, 6', '27, 35', '238, 374');
DECLARE @CATS TABLE (ID int, DESCR varchar(100));
INSERT @CATS (ID, DESCR) VALUES
(1, 'MEN'),
(2, 'WOMEN'),
(3, 'UNISEX'),
(4, 'KIDS'),
(5, 'TEENS'),
(6, 'BACK TO SCHOOL');
DECLARE @SUBCATS TABLE (ID int, DESCR varchar(100));
INSERT @SUBCATS (ID, DESCR) VALUES
(10, 'FOOTWEAR'),
(12, 'OUTERWEAR'),
(14, 'SWIMWEAR'),
(15, 'HOODIES'),
(27, 'CLOTHING'),
(35, 'SPORTS');
DECLARE @SUBSUBCATS TABLE (ID int, DESCR varchar(100));
INSERT @SUBSUBCATS (ID, DESCR) VALUES
(100, 'RUNNING'),
(104, 'ZIP TOPS'),
(135, 'FLEECE'),
(157, 'BIKINIS'),
(238, 'PANTS'),
(374, 'JOGGERS');
SELECT prod.ID,
prod.DESCRIPTION
--CONCAT(cat1.DESCR, ' > ', cat2.DESCR, ' > ', cat3.DESCR) AS CATEGORIES
FROM @PRODUCTS AS prod
--LEFT JOIN @CATS AS cat1 ON cat1.ID = prod.CAT
--LEFT JOIN @SUBCATS AS cat2 ON cat2.ID = prod.SUBCAT
--LEFT JOIN @SUBSUBCATS AS cat3 ON cat3.ID = prod.SUBSUBCAT;
在这种情况下,我想实现以下目标:
- 能够检索猫、子猫、子子猫的各自名称,即。对于猫 '1, 2' 能够检索他们的名字(我试过
LEFT JOIN @CATS AS cat1 ON cat1.ID IN prod.CAT但它不起作用) - 创建相应猫、子猫、子子猫的三元组,即。对于
- 猫'1、2'
- subcats '12, 17'
- sub-subcats '239, 372'
(在检索到适当的名称后)创建管道分隔的类别路由,例如name of cat 1 > name of subcat 12 > name of sub-subcat 239 | name of cat 2 > name of subcat 17 > name of sub-subcat 372
所以,对于像(1, 'NIKE MILLENIUM', '1, 2', '10, 12', '100, 135'), 这样的一行
我想得到以下结果
| ID | DESCRIPTION | CATEGORIES |
|---|---|---|
| 1 | NIKE MILLENIUM | MEN > FOOTWEAR > RUNNING @ WOMEN > OUTERWEAR > FLEECE (I had to use @ as the delimiter of the two triplets because pipe messed with the table's columns) |
如果用户愚蠢地存储了比子猫 ID 或子子猫 ID 更多的猫 ID,则查询应该只匹配具有相应位置匹配的那些,即 for
- 猫'1、2'
- 子目录“12”
- sub-subcats '239, 372'
它应该只创建一个三元组,例如 name of 1 > name of 12 > name of 239
【问题讨论】:
-
显而易见的解决方案是修复你的设计......这是一种糟糕的存储关系的方式,在你修复它之前会一直困扰着你。
-
您实际尝试过什么?选择并不是真正的尝试。你将不得不做一些事情,比如一个字符串拆分,然后是一个连接,然后是一个连接。
-
正如我所说,这太糟糕了,请退后并告诉旨在正确执行此操作的应用程序。但如果没有,看看你的进展如何。
-
你收到的那种分隔的混乱违反了 1NF 并且是一个严重的 PITA。更糟糕的是,在分隔符之后插入了一个空格。啊!!!您将需要在此处使用 string_split,因为您坚持使用此设计。
-
首先是 Sean 这么说的。我还给了你一个开始提示“你将不得不做一些事情,比如一个字符串拆分,然后是一个连接,然后是一个连接。”
标签: sql sql-server tsql sql-server-2014