Sql 基于多对多过滤器的选择
晚上好, 我有一个类似下图的表格布局。用户表存储了我的大部分信息。对于每个用户,我还可以有一个数量不确定的首选项和位置选择,我将其存储在连接表中,如图所示Sql 基于多对多过滤器的选择,sql,sql-server,Sql,Sql Server,晚上好, 我有一个类似下图的表格布局。用户表存储了我的大部分信息。对于每个用户,我还可以有一个数量不确定的首选项和位置选择,我将其存储在连接表中,如图所示 当管理员来生成报告时,他们会像使用过滤器一样使用首选项和位置选择。例如,他们可以选择Preference1和Preference3,以及UserLocation2和UserLocation4,并且报告应仅显示至少具有一个首选项和至少一个位置的用户。是否可以在一个SQL select语句中执行此操作?我正在使用SQLServer2008R2
DECLARE @concatlist VARCHAR(MAX)
SELECT @concatlist = COALESCE(@concatlist+', ', '') + dbo.Preference.Title
FROM dbo.UserPreference
LEFT OUTER JOIN dbo.Preference
ON dbo.UserPreference.PreferenceID = dbo.Preference.PreferenceID
WHERE dbo.UserPreference.UserID = 5
SELECT @concatlist as OutputColumn
任何指点都很好。我花了半天的时间在这个问题上,虽然我可以做到一部分,但我找不到一个方法在一个声明中做到这一点
谢谢,你可以试试这个
WITH UPreference AS (
SELECT u.*,p.*
FROM Users u
INNER JOIN UserPreference up
ON u.UserID = up.UserID
INNER JOIN Preference p
ON up.PreferenceID = p.PreferenceID
)
, ULocation AS (
SELECT u.*,l.*
FROM Users u
INNER JOIN UserLocation ul
ON u.UserID = ul.UserID
INNER JOIN Location l
ON l.LocationID = ul.LocationID
)
SELECT u.*
,AllPreferences = STUFF((SELECT ',' + up.Title FROM UPreference up WHERE up.UserID = u.UserID FOR XML PATH('')) ,1,1,'')
,AllLocations = STUFF((SELECT ',' + ul.[Name] FROM ULocation ul WHERE ul.UserID = u.UserID FOR XML PATH('')) ,1,1,'')
FROM Users u
WHERE
EXISTS(SELECT 1 FROM UPreference up WHERE up.UserID = u.UserID AND up.Title IN ('Preference1','Preference3')
AND
EXISTS(SELECT 1 FROM ULocation ul WHERE ul.UserID = u.UserID AND ul.[Name] IN ('Location2','Location4')
如果您想使用XML数据类型来表示您选择的首选项/位置,那么答案应该很简单 我相信这会解决你的第一个问题:
DECLARE
@prefs xml = '<a><i id="1" /><i id="3" /></a>',
@locs xml = '<a><i id="2" /><i id="3" /></a>'
;WITH p AS (
SELECT
id = c.value('./@id', 'int')
FROM @prefs.nodes('/a/i') T(c)
)
,l AS (
SELECT
id = c.value('./@id', 'int')
FROM @locs.nodes('/a/i') T(c)
)
SELECT *
FROM
[User] u
WHERE
u.UserID IN (
SELECT up.UserID
FROM UserPreference up JOIN p ON p.id = up.PreferenceID)
AND
u.UserID IN (
SELECT ul.UserID
FROM UserLocation ul JOIN l ON l.id = ul.LocationID)
另外,我对TVF、CSV和其他基于集合的输入格式完全失去了兴趣,目前只使用XML。谢谢Eric-做了一些调整,效果非常好,无需在EXISTS语句中比较特定的首选项或位置。
WHERE
u.UserID IN (
SELECT up.UserID
FROM UserPreference up JOIN p ON p.id = up.PreferenceID
INTERSECT
SELECT ul.UserID
FROM UserLocation ul JOIN l ON l.id = ul.LocationID)