Sql 如何根据特殊情况选择数据?
表示我有Sql 如何根据特殊情况选择数据?,sql,sql-server,tsql,Sql,Sql Server,Tsql,表示我有表审计,包含列ID、状态、时间和样本数据,如下所示: 1. {ID = 1, STATUS = 'APPROVE', TIME = '2015-02-01'} 2. {ID = 1, STATUS = 'DECLINE', TIME = '2014-12-01'} 3. {ID = 1, STATUS = 'CLOSED', TIME = '2015-11-01'} 4. {ID = 2, STATUS = 'APPROVE', TIME = '2015-02-01'} 5. {ID =
表审计
,包含列ID、状态、时间和样本数据,如下所示:
1. {ID = 1, STATUS = 'APPROVE', TIME = '2015-02-01'}
2. {ID = 1, STATUS = 'DECLINE', TIME = '2014-12-01'}
3. {ID = 1, STATUS = 'CLOSED', TIME = '2015-11-01'}
4. {ID = 2, STATUS = 'APPROVE', TIME = '2015-02-01'}
5. {ID = 3, STATUS = 'DECLINE', TIME = '2015-10-01'}
6. {ID = 4, STATUS = 'CLOSED', TIME = '2015-02-01'}
有一个条件:如果status='approve'
,则忽略status='decept'
否则选择所有内容
我可以知道如何构造查询以便只获取记录:1,3,4,5,6吗
我目前的方法是首先检索所有状态为“批准”和“已关闭”的数据,并将它们存储到entitable
中,然后将状态为且ID不在@entitable
中的数据存储到@entitable
中。然后最终从@tentable
中选择*
我想知道是否有其他方法来处理这种情况?想法是让所有已经批准的项目都通过,而那些被拒绝的项目则跳过。
我现在无法尝试,但应该可以:
;WITH App (ID, app) AS
(SELECT ID, COUNT(1) FROM #Audit WHERE STATUS = 'APPROVE' GROUP BY ID UNION
SELECT ID, 0 FROM #Audit WHERE ID NOT IN (SELECT ID FROM #Audit WHERE STATUS = 'APPROVE') GROUP BY ID )
SELECT *, ISNULL(App.app, 0)
FROM #Audit LEFT OUTER JOIN App ON #Audit.ID = App.ID
WHERE ISNULL(App.app, 0) = 0 OR (App.app = 1 AND #audit.status != 'DECLINE')
您可以使用窗口功能:
WITH cte AS
(
SELECT *
,[dec] = COUNT(CASE WHEN STATUS = 'DECLINE' THEN 1 END) OVER (PARTITION BY ID)
,[app] = COUNT(CASE WHEN STATUS = 'APPROVE' THEN 1 END) OVER (PARTITION BY ID)
FROM #Audit
)
SELECT ID, STATUS, [TIME]
FROM cte
WHERE NOT ([dec] >= 1 AND [app] >= 1 AND [STATUS] = 'DECLINE');
您的列TIME
可能会产生误导,特别是当它只包含日期时:)@lad2025谢谢,最重要的是因为我不知道数据的功能。stackexchange查询引擎:)在某些情况下(很多行),从审核a2中选择1会更有效。我比较喜欢这个答案+1IMO在此上下文中,select 1
和select*
之间绝对没有性能差异-SQL server无论如何都不会处理/返回所有列。我之所以提到它,是因为它可以在某些上下文中提高性能,而且通常更喜欢选择前1。对于id上的索引以及状态为approve的where子句,请选择1仅执行索引查找。选择*之后还将进行键查找。无论采用哪种方式,通过正确设计表和索引,您的解决方案似乎是最有效的。
select *
from audit a1
where not exists(
select * from audit a2
where a2.status='approve' and a1.status='decline' and a2.id=a1.id
)