晚上好,
我有一个类似于下图的表格布局。 用户表格存储了我的大部分信息。对于每个用户,我还可以选择未确定数量的偏好和位置,我将其存储在联结表中,如图所示。
当管理员来生成报告时,他们将使用首选项和位置选择,如过滤器。例如,他们可以选择Preference1和Preference3,以及UserLocation2和UserLocation4,并且报告应该仅显示具有至少一个首选项和至少一个位置的用户。是否可以在一个SQL select语句中执行此操作?我正在使用SQL Server 2008 R2。
假设用户记录符合上述条件的回报条件,是否可以显示所有首选项和位置,并连接到新列。我已经找到了如何为单个用户获取连接结果,但想知道它是否也可以作为同一SQL select语句的一部分完成。
这就是我为单个UserID ...
返回分隔首选项逗号分隔的内容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
任何指针都会很棒。我已经花了半天时间在这上面,虽然我可以部分地做到这一点,却无法在一个声明中找到方法。
谢谢,
答案 0 :(得分:2)
你可以试试这个
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')
答案 1 :(得分:1)
如果您想使用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)
如果WHERE子句看起来太丑陋,您可以删除superflouos UserID引用并将其替换为以下内容:
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)
P.S。我对TVF,CSV和其他基于集合的输入格式完全失去了兴趣,目前我只使用XML。