【问题标题】:TSQL - Returning single value on if any row exists?SQL - 如果存在任何行,则返回单个值?
【发布时间】:2017-07-26 18:39:50
【问题描述】:

所以我有一个视图,我想为每个用户返回一行,并从其他表中引入(加入)一些字段。一切正常,除了最后一部分。

其中一个表具有与用户关联的多行,如果任何查找行具有值,我希望视图返回的行中的值之一为 0/1。观点:

CREATE VIEW [VW_USER_LIST]
AS
    SELECT  USR.*, 
        UPL.FIRST_NAME, 
        UPL.LAST_NAME, 
        UPL.MIDDLE_INITIAL, 
        UPL.LDAP_DN, 
        UPL.RSS_TOKEN, 
        UPL.LAST_UPDATE_DATE,
        UPL.TIMEZONE, 
        UPL.CULTURE,
        (RTRIM(UPL.FIRST_NAME + ' ' + ISNULL(UPL.MIDDLE_INITIAL,'')) + ' ' + UPL.LAST_NAME) AS FULL_NAME,
        UPOM.ORGANIZATION_ID AS ORGANIZATION_ID,
        UPO.NAME AS ORGANIZATION_NAME,
        UPOM.ORGANIZATION_ROLE_ID AS ORGANIZATION_ROLE_ID,
        CASE WHEN ROL.ROLE_ID IS NULL THEN CONVERT(bit,0) ELSE CONVERT(bit,1) END AS ISINTERNAL
    FROM [USER] AS USR 
        INNER JOIN [USER_PROFILE] AS UPL ON USR.USER_ID = UPL.USER_ID
        LEFT JOIN [USER_ORGANIZATION_MEMBERSHIP] AS UPOM ON USR.USER_ID = UPOM.USER_ID
        LEFT JOIN [ORGANIZATION] AS UPO ON UPOM.ORGANIZATION_ID = UPO.ORGANIZATION_ID
        LEFT JOIN [USER_ROLE] AS URL ON USR.USER_ID = URL.USER_ID
        LEFT JOIN [ROLE] AS ROL ON URL.ROLE_ID = ROL.ROLE_ID AND ROL.IS_INTERNAL=1

我最接近使用的检查是“FROM”之前的最后一个检查,即“CASE”。返回 0 或 1 的 BIT 值。它匹配的 JOIN 是列表中的最后一个 JOIN。

但是,如果用户在USER_ROLE 中有两个在表中标记为IS_INTERNAL=1 的条目,则视图将返回该用户的两个条目。

我明白为什么。

但是,显然我需要使用 EXISTSDISTINCTANY 或其他单数检查该连接 - 但找不到一个很好的例子来说明如何实现这一点 - 如果可能的话

澄清一下,USER_ROLE 表可能有多个USER_ID 条目,交叉引用到ROLE 表。因此,如果用户在USER_ROLE 表中有任何条目与ROLE_IDROLE 表中的条目与IS_INTERNAL = 1 匹配。是的,那里有很多步骤!

【问题讨论】:

  • 当您查看 MSDN 中的 EXISTS() 函数并尝试按照那里的示例进行操作时,您尝试了什么以及遇到了什么错误?
  • 创建视图时不应使用 USR.*。如果 [USER] 表的列有任何更改,将来会给您带来问题。
  • @DVT 是的,我知道。实际视图没有 - 我只是这样做来修剪线条。 :) 不想用 50 多列向问题发送垃圾邮件。 :)

标签: sql-server tsql jointable


【解决方案1】:

这样的?

CREATE VIEW [VW_USER_LIST]
AS
    SELECT  USR.*, 
        UPL.FIRST_NAME, 
        UPL.LAST_NAME, 
        UPL.MIDDLE_INITIAL, 
        UPL.LDAP_DN, 
        UPL.RSS_TOKEN, 
        UPL.LAST_UPDATE_DATE,
        UPL.TIMEZONE, 
        UPL.CULTURE,
        (RTRIM(UPL.FIRST_NAME + ' ' + ISNULL(UPL.MIDDLE_INITIAL,'')) + ' ' + UPL.LAST_NAME) AS FULL_NAME,
        UPOM.ORGANIZATION_ID AS ORGANIZATION_ID,
        UPO.NAME AS ORGANIZATION_NAME,
        UPOM.ORGANIZATION_ROLE_ID AS ORGANIZATION_ROLE_ID,
        ISINTERNAL = cast(case when exists (select 1
                                            from [role] rol
                                            where url.role_id = rol.rol_id
                                                and rol.is_internal = 1) then 1 
                               else 0 
                          end as bit)
    FROM [USER] AS USR 
        INNER JOIN [USER_PROFILE] AS UPL ON USR.USER_ID = UPL.USER_ID
        LEFT JOIN [USER_ORGANIZATION_MEMBERSHIP] AS UPOM ON USR.USER_ID = UPOM.USER_ID
        LEFT JOIN [ORGANIZATION] AS UPO ON UPOM.ORGANIZATION_ID = UPO.ORGANIZATION_ID
        LEFT JOIN [USER_ROLE] AS URL ON USR.USER_ID = URL.USER_ID

【讨论】:

  • 不幸的是,给出了相同的结果。不过,这不是你的错——我忘了​​提到链接。主要问题将使用缺失的信息进行更新。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-04-10
  • 2017-11-24
  • 2019-02-15
  • 1970-01-01
  • 1970-01-01
  • 2019-09-25
  • 2020-04-17
相关资源
最近更新 更多