鉴于以下表格T_DATA.ID = PARENT_ID
或CHILD.ID
姓名:T_DATA
+----+------+--------+
| ID | CODE | VALUE |
+----+------+--------+
| 1 | 3186 | value1 |
| 2 | 3186 | value2 |
| 3 | 3189 | value3 |
| 4 | 3189 | value4 |
| 5 | 3190 | value5 |
+----+------+--------+
姓名:T_DATA_LINK
+-----------+----------+
| PARENT_ID | CHILD_ID |
+-----------+----------+
| 1 | 3 |
| 1 | 4 |
+-----------+----------+
我想返回一个像这样的xml结构:
<ITEM_LIST>
<ITEM>
<CODE>3186</CODE>
<ROWS>
<ROW>
<ID>1</ID>
<ROW_INDEX>0</ROW_INDEX>
<VALUE>value1</VALUE>
</ROW>
<ROW>
<ID>2</ID>
<ROW_INDEX>1</ROW_INDEX>
<VALUE>value2</VALUE>
</ROW>
</ROWS>
</ITEM>
<ITEM>
<CODE>3189</CODE>
<ROWS>
<ROW>
<ID>3</ID>
<ROW_INDEX>0</ROW_INDEX>
<VALUE>value3</VALUE>
</ROW>
<ROW>
<ID>4</ID>
<ROW_INDEX>1</ROW_INDEX>
<VALUE>value4</VALUE>
</ROW>
</ROWS>
</ITEM>
<ITEM>
<CODE>3190</CODE>
<VALUE>value5</VALUE>
</ITEM>
</ITEM_LIST>
每ROW_INDEX
ROW
加1。
我需要T_DATA_LINK
表来了解ITEM
是否有父母。
如果它具有父级,则表示存在多个具有CODE
值的记录,并且它们需要显示为ROWS
,否则必须显示为单个{{1 }}
更新
我实际上需要检查T_DATA_LINK表,因为可能存在ITEM具有父级且只有一条记录的情况,但仍需要将其显示为ROW。
@Shnugo我尝试了你的解决方案,但即使现在我在ROWS中得到正确的值,我也会为每个有多个记录的ITEM获得重复。
这可能是因为我必须将SELECT需要返回的GROUP BY添加到其他字段中,而我没有添加到示例中以保持简单。
例如,对于没有任何行的物品,需要在ITEM级别显示ID。
更新2
@Shnugo你是对的。第3项和第4项是第1项的子项,但您不会在xml中看到这种关系。
所有项目都是独一无二的。
T_DATA_LINK中引用的项目仍然是唯一的,但在我的应用程序中相互链接,它们显示在表格中。 基本上,PARENT是表格的第一列,孩子是其他列。
这是我想要的更新输出。
对于有行的项,ID应始终为-1。
PARENT_CODE应该是父项的CODE(如果项目是父项,那么它等于CODE)
ITEM
答案 0 :(得分:2)
这是一个新的答案......请尽量将所有需要的信息放入最初的问题......
DECLARE @t_data TABLE(ID INT,CODE INT,VALUE VARCHAR(100));
INSERT INTO @t_data VALUES
(1,3186,'value1')
,(2,3186,'value2')
,(3,3189,'value3')
,(4,3189,'value4')
,(5,3190,'value5');
DECLARE @t_data_link TABLE(PARENT_ID INT, CHILD_ID INT)
INSERT INTO @t_data_link VALUES
(1,3)
,(1,4);
- CTE链接两个表并允许将它们作为一个派生的表处理
WITH Combined AS
(
SELECT d.*
,d2.CODE AS PARENT_CODE
,COUNT(*) OVER(PARTITION BY d.CODE) AS CountRows
FROM @t_data AS d
LEFT JOIN @t_data_link AS dl ON d.ID=dl.CHILD_ID
LEFT JOIN @t_data AS d2 ON dl.PARENT_ID=d2.ID
)
SELECT CASE WHEN c.CountRows>1 THEN -1 END AS ID
,CASE WHEN c.CountRows>1 THEN c.CODE END AS CODE
,CASE WHEN c.CountRows>1 THEN ISNULL(c.PARENT_CODE,c.CODE) END AS PARENT_CODE
--This part for elements with just one row per code
,(
SELECT d2.ID
,d2.CODE
,d2.VALUE
FROM @t_data AS d2
WHERE c.CODE=d2.CODE
AND c.CountRows=1
FOR XML PATH(''),TYPE
)
--This part for elements with more rows per code
,(
SELECT d2.ID
,ROW_NUMBER() OVER(ORDER BY (SELECT NULL))-1 AS ROW_INDEX
,d2.VALUE
FROM @t_data AS d2
WHERE c.CODE=d2.CODE
AND c.CountRows>1
FOR XML PATH('ROW'),ROOT('ROWS'),TYPE
)
FROM Combined AS c
GROUP BY c.CODE,c.CountRows,c.PARENT_CODE
FOR XML PATH('ITEM'),ROOT('ITEM_LIST');
结果
<ITEM_LIST>
<ITEM>
<ID>-1</ID>
<CODE>3186</CODE>
<PARENT_CODE>3186</PARENT_CODE>
<ROWS>
<ROW>
<ID>1</ID>
<ROW_INDEX>0</ROW_INDEX>
<VALUE>value1</VALUE>
</ROW>
<ROW>
<ID>2</ID>
<ROW_INDEX>1</ROW_INDEX>
<VALUE>value2</VALUE>
</ROW>
</ROWS>
</ITEM>
<ITEM>
<ID>-1</ID>
<CODE>3189</CODE>
<PARENT_CODE>3186</PARENT_CODE>
<ROWS>
<ROW>
<ID>3</ID>
<ROW_INDEX>0</ROW_INDEX>
<VALUE>value3</VALUE>
</ROW>
<ROW>
<ID>4</ID>
<ROW_INDEX>1</ROW_INDEX>
<VALUE>value4</VALUE>
</ROW>
</ROWS>
</ITEM>
<ITEM>
<ID>5</ID>
<CODE>3190</CODE>
<VALUE>value5</VALUE>
</ITEM>
</ITEM_LIST>
XML将省略任何NULL值。如果找不到任何内容,则子选择中的WHERE
子句将返回NULL
...