【问题标题】:Filtering SQL rows based on values from other rows根据其他行的值过滤 SQL 行
【发布时间】:2020-02-18 08:01:08
【问题描述】:

使用 SQL Server 2016 SP1 数据库,我在表名 AgentsTable 中有这些数据:

从代理表中选择 *;

user_id         first_name  last_name   agent_id   agent_status  agent_code
2003015038088   John        Brown       22307      Retired       12345
2003015038088   John        Brown       22307      Death         12399
4432442556456   Mary        Jane        24667      Active        32133
7746234737464   Harry       Smith       29981      Retired       42354
3455555657677   Mark        Aguy        29654      Active        34655
5436546674465   Sally       Sam         22584      Retired       45464

第二行显示“John Brown”已死(agent_status = 'Death'),因此我想排除已死的 agent_id 的所有行。 (请注意,John Brown 有两个不同的 agent_code,因此每个 agent_code 有一行。源数据就是这样......)

这个查询:

SELECT * FROM AgentsTable WHERE agent_status = 'Retired';

会返回这个:

user_id          first_name   last_name    agent_id   agent_status  agent_code
2003015038088    John         Brown        22307      Retired       12345
7746234737464    Harry        Smith        29981      Retired       42354
5436546674465    Sally        Sam          22584      Retired       45464

排除 John Brown (22307) 后,我想要的结果是:

user_id          first_name   last_name    agent_id   agent_status  agent_code
7746234737464    Harry        Smith        29981      Retired       42354
5436546674465    Sally        Sam          22584      Retired       45464

我怎样才能做到这一点?换句话说,如何根据另一相关行中的值排除一行?

【问题讨论】:

  • 你从“死亡”到“退休”,没有任何解释。有点奇怪,同一个代理也有 2 个不同的 agent_code 值 - 但也许列名选择不当。既然您提到了代码列-您为什么要这样做?代理代码如何影响结果?马克和玛丽怎么了?他们与 22307 没有任何关系。您是否只是在搜索所有也没有关联“死亡”行的退休特工?
  • 如果有 Death 和 Retired 记录,这可能意味着该代理人在退休后去世(领取养老金)。 “业务规则”说,agent_code 不允许有多个不同的值,但实际上确实会发生。我无法控制创建代理代码的人......马克和玛丽是“活跃的”,所以他们不是“Reired”或“Death”(死亡)。他们与 22307 没有任何关系。是的,我想要一份所有还活着的退休特工的名单(不是 =“死亡”)。

标签: sql sql-server tsql


【解决方案1】:

您可以使用 CTE 并获取未死亡的代理,如下所示:

;WITH CTE_deceasedagents AS
(
SELECT agent_id
FROM AgentsTable
WHERE agent_status = 'Death'
)
SELECT *
FROM AgentsTable as a
WHERE NOT EXISTS
(
SELECT agent_id
FROM CTE_deceasedagents as c
WHERE c.agent_id = a.agent_id
);
GO

【讨论】:

    【解决方案2】:

    SELECT * FROM AgentsTable t1 WHERE agent_status = 'Retired' where NOT EXISTS(SELECT 1 FROM AgentsTable t2 WHERE t2.agent_status = 'Death' and t2.agent_code = t1.agent_code );

    【讨论】:

      【解决方案3】:

      我只会将not exists 与相关子查询一起使用,以确保不存在具有相同user_id'Death' 状态的其他记录:

      select a.*
      from agentsTable a
      where not exists (
          select 1
          from agentsTable a1
          where a1.user_id = a.user_id and a1.agent_status = 'Death'
      )
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-08-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-12-22
        • 2021-07-15
        • 1970-01-01
        相关资源
        最近更新 更多