【问题标题】:How to select a particular type and exclude others in a query如何在查询中选择特定类型并排除其他类型
【发布时间】:2023-03-18 14:07:01
【问题描述】:

只是想知道是否可以在 SSMS 中选择仅使用特定类型而不使用其他任何内容的行。

例如:

╔════════╦══════╗
║ UserID ║ Type ║
╠════════╬══════╣
║      1 ║ A    ║
║      1 ║ B    ║
║      1 ║ C    ║
║      1 ║ D    ║
║      2 ║ D    ║
║      3 ║ A    ║
║      3 ║ C    ║
║      3 ║ D    ║
║      4 ║ B    ║
║      4 ║ C    ║
║      5 ║ C    ║
║      5 ║ D    ║
╚════════╩══════╝

现在,我正在寻找个人资料中只有 D 而没有其他内容的用户。对于上面的示例,UserID 2 将是查询的结果。

【问题讨论】:

  • 是的,有可能——这能回答你的问题吗? :) 到目前为止你尝试过什么?
  • 我相信@Arvo希望你自己解决问题,因为答案很简单。
  • 我不太擅长 SQL。这就是我来这里寻求擅长它的帮助的原因。我确实尝试解决我的查询但没有成功。我尝试了一个类似的查询,正如下面建议的答案中所建议的那样。

标签: sql sql-server sql-server-2008 ssms ssms-2012


【解决方案1】:

正如@Gordon 建议的那样,您的数据库设计非常糟糕,请尝试修复它。下面的查询无论如何都会做你的工作 -

CREATE TABLE #UserIDType( UserID int,   Type char(1))
insert into #UserIDType
select 1  ,      'A' union all
select 1 ,       'B' union all
select 1 ,       'C' union all
select 1,        'D' union all
select 2,        'D' union all
select 3,        'A' union all
select 3,        'C' union all
select 3,        'D' union all
select 4,        'B' union all
select 4,        'C' union all
select 5,        'C' union all
select 5,        'D'
select userid,type from
(select *,row_number() over(partition by userid order by userid) rn 
from #useridtype) a 
where type='D' and rn=1

【讨论】:

  • 如果有记录2, 'E'呢?
  • 在这种情况下,我会尝试这个查询 - select userid from (select userid,count(rn) cnt from (select *,row_number() over(partition by userid order by userid) rn from #useridtype) a --where type='D' group by userid) b where cnt = 1
【解决方案2】:
SELECT DISTINCT T1.*
FROM YourTable T1
LEFT JOIN YourTable T2 ON T1.UserID = T2.UserID AND T2.Type <> 'D'
WHERE T1.Type = 'D' AND T2.UserID IS NULL

解释:

SELECT *
FROM Table
WHERE Type = 'D'

将选择 Type = 'D' 的所有记录。

SELECT T1.*
FROM Table T1
LEFT JOIN Table T2 ON T1.UserID = T2.UserID AND T2.Type <> 'D'

将选择所有类型在 'D' 旁边的记录

添加WHERE T2.UserID IS NULL 选择除了“D”之外没有任何其他类型的记录。

结合这两个结果集得到最终结果。

【讨论】:

    【解决方案3】:
    SELECT 
        UserID
    FROM
        [Table] 
    GROUP BY 
        UserID HAVING COUNT(UserID)=1 and Type='D'
    

    【讨论】:

      【解决方案4】:

      你的数据结构很差,你应该专注于修复它。将值存储在分隔列表中是一个非常糟糕的主意,也不是关系数据库的好用处。相反,您需要一个 UserTypes 表,其中每个用户一行,每种类型一行。

      但是,有时我们会被其他人糟糕的设计选择所困扰。在这种情况下,您的特定问题的答案很简单:

      select t.*
      from t
      where Type = 'D';
      

      编辑:

      对于改进的数据结构:

      select userId
      from t
      group by userId
      having min(type) = 'D' and max(type) = 'D';
      

      【讨论】:

      • 我曾为我的问题尝试过类似的查询。但它会带回所有类型 = 'D' 的用户。我正在寻找只有“D”的用户标识
      • @Raja 。 . .这应该只带回在Type 字段中具有精确“D”的用户。您应该使用您正在使用的查询来编辑您的问题。
      • @Gordon..我现在已经编辑了我的示例。我想将类型作为逗号分隔值并不能解决我的问题。现在,如果我们应用您建议的查询,它将带回用户 ID 1、2、3 和 5。但是,我正在寻找仅返回用户 ID 2,因为它没有任何其他关联类型。希望这会有所帮助
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-04-16
      • 1970-01-01
      • 2021-09-29
      • 1970-01-01
      • 1970-01-01
      • 2016-04-04
      • 2013-04-18
      相关资源
      最近更新 更多