示例题目:
有如下一张表T0624A

T0624B

希望得到如下结果:

该如何写这个SQL?
示例数据:
CREATE TABLE T0624A
(
用户编号 VARCHAR(10),
用户地址 VARCHAR(20),
金额 INT
)
INSERT INTO T0624A VALUES
('001','花开村1号',10),
('002','花开村2号',15),
('003','花开村6号',15),
('004','花开村5号',16),
('005','花开村12号',8)
CREATE TABLE T0624B
(
微信用户订单号 VARCHAR(10),
用户编号 VARCHAR(50)
)
INSERT INTO T0624B VALUES
('90002','001,002,004'),
('90003','005')
查询sql:
WITH T AS (
SELECT
tb01.微信用户订单号
,tb02.VALUE
FROM(
SELECT
微信用户订单号
,[value] = CONVERT(xml,'<root><v>' + REPLACE(用户编号, ',', '</v><v>') + '</v></root>')
FROM T0624B ) AS tb01
OUTER APPLY(
SELECT
VALUE = N.v.value('.', 'varchar(100)') FROM tb01.[value].nodes('/root/v'
) N(v) ) AS tb02
)
SELECT A.*,T.微信用户订单号
FROM T0624A A
LEFT JOIN T ON A.用户编号 = T.VALUE
思路解析:
outer apply用法参考:https://www.cnblogs.com/ljhdo/p/4422622.html
outer apply 和cross apply的相同点是:
- 先计算左表,后计算右表;
- 对左表中的每一行记录,右表都要“逐行”计算,类似于相关子查询;
outer apply 和cross apply的不同点是:
- outer apply:将左表作为保留表,如果右表没有匹配行,那么右表中的字段会设置为null,类似于left join。
- cross apply:没有保留表,对于左表中的一行记录,如果右表中没有匹配行,那么该行记录不显示在最终结果集中,类似于inner join。
其中子查询部分可以改成自定义函数,参考:https://www.cnblogs.com/wangfuyou/p/5854218.html
CREATE FUNCTION [dbo].[ufn_SplitStringToTable]
(
@str VARCHAR(MAX) ,
@split VARCHAR(10)
)
RETURNS TABLE
AS
RETURN
( SELECT B.id
FROM ( SELECT [value] = CONVERT(XML , '<v>' + REPLACE(@str , @split , '</v><v>')
+ '</v>')
) A
OUTER APPLY ( SELECT id = N.v.value('.' , 'varchar(100)')
FROM A.[value].nodes('/v') N ( v )
) B
)

浙公网安备 33010602011771号