FOR XML 具有查找文本值的查询
FOR XML query with lookup texual values
我正在尝试为此寻找解决方案;
在 Azure SQL 主数据库中(事实)table 我有
category_1_id category_2_id category_3_id
------------------------------------------
1000 2000 3001
1000 2000 3002
和第二个 table 是非规范化的,需要保持与结构相同
cat_1_id cat_2_id cat_3_id cat_1_name cat_2_name cat_3_name
-----------------------------------------------------------------
1000 2000 3001 Name1 Name2 Title1
1000 2000 3002 Name1 Name2 Title2
我需要从主 table 中导出 XML,其中的文本值基于第二个 table 中所有三个类别名称的类别 ID。 FOR XML 的查询已完成,但具有数字 ID 的值。
第二个 table 没有主键也没有关系,我不确定我是否可以有任何关系..需要像查找一样工作。
有什么想法吗?
从 OP 给出的不应该是答案的答案中复制:
输出现在是这样的
<category_1_id>1000</category_1_id>
<category_2_id>2000</category_2_id>
<category_3_id>3001</category_3_id>
并且需要
<category_1_id>Name1</category_1_id>
<category_2_id>Name2</category_2_id>
<category_3_id>Name3</category_3_id>
老实说:这个设计太糟糕了。如果你看到丝毫改变这一点的机会,你真的应该去标准化。
总之,这个是可以做到的(但我不确定我是否真的理解你的需求)...
我从两个声明的 table 变量开始,到 mock-up 你的场景:
DECLARE @mainTable TABLE(category_1_id INT,category_2_id INT,category_3_id INT)
INSERT INTO @mainTable VALUES (1000,2000,3001);
DECLARE @catalog TABLE(cat_1_id INT,cat_2_id INT, cat_3_id INT, cat_1_name VARCHAR(100),cat_2_name VARCHAR(100), cat_3_name VARCHAR(100));
INSERT INTO @catalog VALUES
(1000,2000,3001,'Name1','Name2','Title1')
,(1000,2000,3002,'Name1','Name2','Title2');
第一种方法使用三个 TOP 1
sub-selects
SELECT DISTINCT
(SELECT TOP 1 c.cat_1_name FROM @catalog AS c WHERE c.cat_1_id=m.category_1_id) AS category_1_id
,(SELECT TOP 1 c.cat_2_name FROM @catalog AS c WHERE c.cat_2_id=m.category_2_id) AS category_2_id
,(SELECT TOP 1 c.cat_3_name FROM @catalog AS c WHERE c.cat_3_id=m.category_3_id) AS category_3_id
FROM @mainTable AS m
FOR XML PATH('');
第二种方法使用 VALUES
创建第二个 table 的派生 table,其 ID 和名称各占一行 (unpivot
)。此 table 可以加入主 table 的列。
WITH CatalogValues AS
(
SELECT DISTINCT UnpivotedCatalog.*
FROM @catalog AS c
CROSS APPLY(VALUES(c.cat_1_id,c.cat_1_name)
,(c.cat_2_id,c.cat_2_name)
,(c.cat_3_id,c.cat_3_name)) AS UnpivotedCatalog(id,name)
)
SELECT DISTINCT
cv1.name AS category_1_id
,cv2.name AS category_2_id
,cv3.name AS category_3_id
FROM @mainTable AS m
LEFT JOIN CatalogValues AS cv1 ON m.category_1_id=cv1.id
LEFT JOIN CatalogValues AS cv2 ON m.category_2_id=cv2.id
LEFT JOIN CatalogValues AS cv3 ON m.category_3_id=cv3.id
FOR XML PATH('')
两种情况的结果相同:
<category_1_id>Name1</category_1_id>
<category_2_id>Name2</category_2_id>
<category_3_id>Title1</category_3_id>
当我继续这个任务时,我 运行 遇到了另一个问题.. 如果有人有时间检查 https://dba.stackexchange.com/questions/163658/ms-sql-db-design-help
谢谢
我正在尝试为此寻找解决方案; 在 Azure SQL 主数据库中(事实)table 我有
category_1_id category_2_id category_3_id
------------------------------------------
1000 2000 3001
1000 2000 3002
和第二个 table 是非规范化的,需要保持与结构相同
cat_1_id cat_2_id cat_3_id cat_1_name cat_2_name cat_3_name
-----------------------------------------------------------------
1000 2000 3001 Name1 Name2 Title1
1000 2000 3002 Name1 Name2 Title2
我需要从主 table 中导出 XML,其中的文本值基于第二个 table 中所有三个类别名称的类别 ID。 FOR XML 的查询已完成,但具有数字 ID 的值。
第二个 table 没有主键也没有关系,我不确定我是否可以有任何关系..需要像查找一样工作。
有什么想法吗?
从 OP 给出的不应该是答案的答案中复制:
输出现在是这样的
<category_1_id>1000</category_1_id>
<category_2_id>2000</category_2_id>
<category_3_id>3001</category_3_id>
并且需要
<category_1_id>Name1</category_1_id>
<category_2_id>Name2</category_2_id>
<category_3_id>Name3</category_3_id>
老实说:这个设计太糟糕了。如果你看到丝毫改变这一点的机会,你真的应该去标准化。
总之,这个是可以做到的(但我不确定我是否真的理解你的需求)...
我从两个声明的 table 变量开始,到 mock-up 你的场景:
DECLARE @mainTable TABLE(category_1_id INT,category_2_id INT,category_3_id INT)
INSERT INTO @mainTable VALUES (1000,2000,3001);
DECLARE @catalog TABLE(cat_1_id INT,cat_2_id INT, cat_3_id INT, cat_1_name VARCHAR(100),cat_2_name VARCHAR(100), cat_3_name VARCHAR(100));
INSERT INTO @catalog VALUES
(1000,2000,3001,'Name1','Name2','Title1')
,(1000,2000,3002,'Name1','Name2','Title2');
第一种方法使用三个 TOP 1
sub-selects
SELECT DISTINCT
(SELECT TOP 1 c.cat_1_name FROM @catalog AS c WHERE c.cat_1_id=m.category_1_id) AS category_1_id
,(SELECT TOP 1 c.cat_2_name FROM @catalog AS c WHERE c.cat_2_id=m.category_2_id) AS category_2_id
,(SELECT TOP 1 c.cat_3_name FROM @catalog AS c WHERE c.cat_3_id=m.category_3_id) AS category_3_id
FROM @mainTable AS m
FOR XML PATH('');
第二种方法使用 VALUES
创建第二个 table 的派生 table,其 ID 和名称各占一行 (unpivot
)。此 table 可以加入主 table 的列。
WITH CatalogValues AS
(
SELECT DISTINCT UnpivotedCatalog.*
FROM @catalog AS c
CROSS APPLY(VALUES(c.cat_1_id,c.cat_1_name)
,(c.cat_2_id,c.cat_2_name)
,(c.cat_3_id,c.cat_3_name)) AS UnpivotedCatalog(id,name)
)
SELECT DISTINCT
cv1.name AS category_1_id
,cv2.name AS category_2_id
,cv3.name AS category_3_id
FROM @mainTable AS m
LEFT JOIN CatalogValues AS cv1 ON m.category_1_id=cv1.id
LEFT JOIN CatalogValues AS cv2 ON m.category_2_id=cv2.id
LEFT JOIN CatalogValues AS cv3 ON m.category_3_id=cv3.id
FOR XML PATH('')
两种情况的结果相同:
<category_1_id>Name1</category_1_id>
<category_2_id>Name2</category_2_id>
<category_3_id>Title1</category_3_id>
当我继续这个任务时,我 运行 遇到了另一个问题.. 如果有人有时间检查 https://dba.stackexchange.com/questions/163658/ms-sql-db-design-help
谢谢