【问题标题】:Join all items in 4 tables allowing nulls加入 4 个允许空值的表中的所有项目
【发布时间】:2013-07-26 13:28:24
【问题描述】:

我正在研究一个培训计划,但我无法弄清楚 SQL 查询。 我有 4 个表:userProfilesTbl、trainingTbl、userAssessmentTbl 和 setsTbl userProfilesTbl 和 userAssessmentsTbl 通过 UserId fkey 关联,这是一个唯一的身份字段类型。

trainingTbl 和 userAssessmentTbl 通过 tt_id fkey INT 字段类型关联。 setsTbl 和 trainingTbl 通过 s_id fkey INT 字段类型关联。

trainingTbl 填充了指定用户组在指定日期进行的培训。

userAssessmentTbl 由个人用户培训(结果、注释等)填充。

userProfilesTbl 包含所有未包含在成员资格和角色框架中的附加用户信息(连接到 aspnet_users 表)。

setsTbl 由不同训练类型的列表填充。

我想显示所有训练集和用户,无论他们是否完成了训练。

Gridview(这是一个 PIVOT 表)应该从 userProfilesTbl 返回 surName,从 setsTbl 返回 setName,从 userAssessmentTbl 返回结果(值)。
目前我有 2 个选择语句

  1. 显示没有任何训练结果的 setName 和 surname

    Dim query As String = "SELECT * FROM userProfilesTbl LEFT OUTER JOIN userAssessmentTbl ON userProfilesTbl.UserId = userAssessmentTbl.UserId LEFT OUTER JOIN trainingTbl ON userAssessmentTbl.tt_id = trainingTbl.tt_id LEFT OUTER JOIN setsTbl ON trainingTbl.s_id = setsTbl.s_id WHERE userProfilesTbl.st_id=@st_id AND userProfilesTbl.wa_id=@wa_id AND DATEPART(mm,t_date) = @m_date AND DATEPART(yyyy,t_date) = @y_date ORDER BY surname ASC

  2. 显示训练结果 setName,仅显示完成训练的用户的姓氏,并且仅显示他们进行的训练。不显示所有其他用户和培训。

    SELECT * FROM userProfilesTbl, setsTbl, userAssessmentTbl, trainingTbl WHERE (userProfilesTbl.UserId = userAssessmentTbl.UserId) AND (userAssessmentTbl.tt_id = trainingTbl.tt_id) AND userProfilesTbl.st_id=@st_id AND userProfilesTbl.wa_id=@wa_id AND DATEPART(mm,t_date) = @m_date AND DATEPART(yyyy,t_date) = @y_date ORDER BY surname ASC

我有什么建议吗?

【问题讨论】:

    标签: sql join null group-by


    【解决方案1】:

    您使用哪种数据库系统? 除了LEFT/RIGHT OUTER JOIN,许多系统还支持FULL OUTER JOIN。 这会返回双方没有另一方合作伙伴的记录。

    编辑:

    SELECT * 
      FROM userProfilesTbl
      FULL OUTER JOIN userAssessmentTbl ON userProfilesTbl.UserId = userAssessmentTbl.UserId
      FULL OUTER JOIN trainingTbl ON userAssessmentTbl.tt_id = trainingTbl.tt_id
      FULL OUTER JOIN setsTbl ON trainingTbl.s_id = setsTbl.s_id
     ORDER BY surname ASC
    

    应该向您显示表格中包含的所有数据。 如果您随后使用 WHERE 限制数据,则还会排除用于 WHERE 条件的列中具有空值的行。

    因此,你应该使用类似

    的东西
    SELECT * 
      FROM userProfilesTbl
      FULL OUTER JOIN userAssessmentTbl ON userProfilesTbl.UserId = userAssessmentTbl.UserId
      FULL OUTER JOIN trainingTbl ON userAssessmentTbl.tt_id = trainingTbl.tt_id
      FULL OUTER JOIN setsTbl ON trainingTbl.s_id = setsTbl.s_id
     WHERE (userProfilesTbl.st_id=@st_id OR userProfilesTbl.st_id IS NULL)
       AND (userProfilesTbl.wa_id=@wa_id OR userProfilesTbl.wa_id IS NULL)
       AND ((DATEPART(mm,t_date) = @m_date AND DATEPART(yyyy,t_date) = @y_date) OR t_date IS NULL)
     ORDER BY surname ASC
    

    您的第二个陈述可能可以类似地调整。

    【讨论】:

    • 我正在使用 Microsoft SQL Server (Express) 数据库系统。当我在上面的语句中使用 FULL OUTER JOIN 时,返回是相同的。
    • 您是否还在FROM/WHERE 的第二个语句insterad 中使用了FULL OUTER JOINs?此外,您可能想添加类似 (userProfilesTbl.st_id=@st_id OR userProfilesTbl.st_id IS NULL) 的内容以包含不匹配的内容。
    • 是的,我也使用了 FULL OUTER JOIN 无济于事!您答案的第二部分将 IS NULL 放在组 st.id 上说 shop 和 wa_id 是一个转变。因此,因此将 IS NULL 删除了过滤组的方法。
    • 试图继续这个线程可以请其他人帮忙吗?很重要!
    • 嗨,FrankPi,我让你在上面编辑了代码,但是这是不正确的!
    猜你喜欢
    • 2011-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-27
    • 1970-01-01
    • 2011-02-14
    • 2013-08-26
    相关资源
    最近更新 更多