我正在尝试根据从用户收到的表列表构建动态查询。 我在下面有几个尝试过的解决方案。 我认为CTE是要走的路,但我很难弄清楚如何实现它。 我真的很感激天才能让我知道如何做到这一点!
这些是表格: W,WD,WE,WSF,WSFE,XDF,XDFE,Y,YD,Z,ZD
这些是每组表加入的列:
W,Y,WD,WE,WSF
WID
WSF,WSFE,XDF
WSFID
XDF,XDFE
XDFID
Y,YD,Z
YID
Z,ZD
ZID
如果用户选择W,Y,Z,则构建此查询(然后可以由exec或sp_executesql执行): select * from #W w join yY on y.WID = w.WID join zZ on z.YID = y.YID
declare @Fields table (
ID int identity not NULL,
Name varchar(200)
)
declare @Tables table (
ID int identity not NULL,
Field varchar(200),
TempTable varchar(200)
)
declare @QueryTables table (
ID int identity not NULL,
[Table] varchar(200),
Alias varchar(20)
)
declare @QueryJoins table (
ID int identity not NULL,
Table1 varchar(20),
Col1 varchar(200),
Table2 varchar(20),
Col2 varchar(200)
)
insert @Fields
values
('W'),
('Y'),
('Z')
insert @Tables
values
('W', '#W'),
('WD', '#WD'),
('WE', '#WE'),
('WSF', '#WSF'),
('WSFE', '#WSFE'),
('XDF', '#XDF'),
('XDFE', '#XDFE'),
('Y', '#Y'),
('YD', '#YD'),
('Z', '#Z'),
('ZD', '#ZD')
insert @QueryTables
values
('#W', 'w'),
('#WD', 'wd'),
('#WE', 'we'),
('#WSF', 'wsf'),
('#WSFE', 'wsfe'),
('#XDF', 'xdf'),
('#XDFE', 'xdfe'),
('#Y', 'y'),
('#YD', 'yd'),
('#Z', 'z'),
('#ZD', 'zd')
insert @QueryJoins
values
('w', 'WID', 'wd', 'WID'),
('w', 'WID', 'we', 'WID'),
('w', 'WID', 'wsf', 'WID'),
('w', 'WID', 'xdf', 'WID'),
('w', 'WID', 'y', 'WID'),
('wd', 'WID', 'w', 'WID'),
('we', 'WID', 'wd', 'WID'),
('wsf', 'WID', 'wd', 'WID'),
('wsf', 'WSFID', 'wsfe', 'WSFID'),
('wsfe', 'WSFID', 'wsf', 'WSFID'),
('wsf', 'WSFID', 'xdf', 'WSFID'),
('xdf', 'WID', 'w', 'WID'),
('xdf', 'WSFID', 'wsf', 'WSFID'),
('xdf', 'XDFID', 'xdfe', 'XDFID'),
('xdfe', 'XDFID', 'xdf', 'XDFID'),
('y', 'WID', 'w', 'WID'),
('y', 'YID', 'yd', 'YID'),
('yd', 'YID', 'y', 'YID'),
('y', 'YID', 'z', 'YID'),
('z', 'YID', 'y', 'YID'),
('z', 'ZID', 'zd', 'ZID'),
('zd', 'ZID', 'z', 'ZID')
--attempted solution number 1:
select
*
from @Fields vf
join @Tables vt
on vt.Field = vf.Name
join @QueryTables vqt
on vqt.[Table] = vt.TempTable
join @QueryJoins vqj
on vqj.Table1 = vqt.Alias
join @QueryTables vqt2
on vqt2.Alias = vqj.Table2
join @Tables vt2
on vt2.TempTable = vqt2.[Table]
join @Fields vf2
on vf2.Name = vt2.Field
--attempted solution number 2:
;with cte (FieldID, [Table], Table1, Col1, Table2, Col2, I) as (
select
vf.ID as FieldID,
vqt.[Table],
vqj.Table1,
vqj.Col1,
vqj.Table2,
vqj.Col2,
1
from @Fields vf
join @Tables vt
on vt.Field = vf.Name
join @QueryTables vqt
on vqt.[Table] = vt.TempTable
join @QueryJoins vqj
on vqj.Table1 = vqt.Alias
union all
select
vf.ID as FieldID,
vqt.[Table],
vqj.Table1,
vqj.Col1,
vqj.Table2,
vqj.Col2,
I + 1
from @Fields vf
join @Tables vt
on vt.Field = vf.Name
join @QueryTables vqt
on vqt.[Table] = vt.TempTable
join @QueryJoins vqj
on vqj.Table1 = vqt.Alias
join cte cte
on cte.Table1 = vqj.Table2
and cte.Table2 = vqj.Table1
where I <= FieldID --a feeble attempt to control the recursion
)
select * from cte
答案 0 :(得分:0)
一个有趣的问题,绝对是数据建模代码的味道(如果Z,Y和YD都有YID列,听起来你需要一个桥表或类似的结构来管理那里的关系。或者如果Z和YD很小查找,只需加入它们,让优化器处理开销。)
注意:我在名称&lt;上创建了字段自连接名称,所以你只需要Table1&lt;中的QueryJoins数据。表2。这会将你的QueryJoins表减少一半,但你也错过了一些“正确的”连接(即你有我们/ wd而不是wd /我们)
{{1}}