Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 基于多对多过滤器的选择_Sql_Sql Server - Fatal编程技术网

Sql 基于多对多过滤器的选择

Sql 基于多对多过滤器的选择,sql,sql-server,Sql,Sql Server,晚上好, 我有一个类似下图的表格布局。用户表存储了我的大部分信息。对于每个用户,我还可以有一个数量不确定的首选项和位置选择,我将其存储在连接表中,如图所示 当管理员来生成报告时,他们会像使用过滤器一样使用首选项和位置选择。例如,他们可以选择Preference1和Preference3,以及UserLocation2和UserLocation4,并且报告应仅显示至少具有一个首选项和至少一个位置的用户。是否可以在一个SQL select语句中执行此操作?我正在使用SQLServer2008R2

晚上好,

我有一个类似下图的表格布局。用户表存储了我的大部分信息。对于每个用户,我还可以有一个数量不确定的首选项位置选择,我将其存储在连接表中,如图所示

  • 当管理员来生成报告时,他们会像使用过滤器一样使用首选项和位置选择。例如,他们可以选择Preference1和Preference3,以及UserLocation2和UserLocation4,并且报告应仅显示至少具有一个首选项和至少一个位置的用户。是否可以在一个SQL select语句中执行此操作?我正在使用SQLServer2008R2

  • 假设用户记录符合上述返回条件,是否有方法显示其所有首选项和位置,并连接到一个新列中。我已经知道了如何为单个用户返回连接结果,但不知道是否也可以作为同一个SQL select语句的一部分来完成

  • 这是我用来返回个人用户ID的首选项逗号分隔

    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)