2013-10-24 131 views
0

我必须从产品中选择最低状态后,选择每个产品的最高状态。我的查询是如何在选择最大值后选择分钟

select A. Name 
B.LineState 
from table A 
join table B on A.id=B.refid 
where B.Linestate = (select max(B2.Linestate) 
        from table B2 
        where B.refid=B2.refid) 

这工作正常,并给出正确的行。现在我必须从我之前获得的最小LineState中选择。我曾尝试过:

... 
where B.Linestate = min((select max(B2.linestate) 
         from table B2 
         where B.refid=B2.refid)) 

不幸的是它不起作用。我如何从先前选择的最大值组中获得最小值?

+0

有没有遇到麻烦的CTE工作?如果你没有使用太多的行,其他的答案会有效,但是在数据集较大的情况下,CTE效率会更高。 –

+1

不,我没有遇到任何麻烦,然而D Stanley的'其他'答案对我来说更加清晰易懂。两者都有效。你的看起来更加复杂。感谢帮助。这是一个可惜我不能标记两个答案被接受。 – relaj

+0

不用担心!确实,斯坦利的理解更容易,但正如我所说,效率低下很多,而我的惯例实际上很常见。如果您最终在现实世界中使用代码(我的意思是在工作或客户的程序中),则还有其他解决方案,并且出于可伸缩性和性能原因,您希望避免子查询并在可能的地方交叉应用。 –

回答

0

你可以只让你的第一个查询的子查询:

SELECT MIN(LineState) 
FROM 
(
    select A. Name 
    B.LineState 
    from table A 
    join table B on A.id=B.refid 
    where B.Linestate=(select max(B2.Linestate) from table B2 where B.refid=B2.refid) 
) 

或者,如果你想要的名称太:

SELECT TOP 1 * 
FROM 
(
    select A. Name 
    B.LineState 
    from table A 
    join table B on A.id=B.refid 
    where B.Linestate=(select max(B2.Linestate) from table B2 where B.refid=B2.refid) 
) 
ORDER BY Linestate 
+0

这些答案的服务器效率有显着差异吗?我的意思是解决方案SELECT MIN与GetMax ...来自GetMax。 – relaj

+0

可能不会 - 除非您在多个位置或递归使用CTE,否则计划应与子查询几乎完全相同。 –

4

Common Table Expressions是这个问题的一个很好的解决方案。他们让你得到你想要的设置,然后立即从那里拉出一个子集。

; WITH GetMaxList AS (
select A. Name 
B.LineState 
from table A 
join table B on A.id=B.refid 
where B.Linestate=(select max(B2.Linestate) from table B2 where B.refid=B2.refid) 
) 

SELECT MIN([Column]) 
FROM GetMaxList 

请记住,这只是示例代码。如果您复制粘贴它,它将不起作用。你需要做一些小小的阅读来弄清楚如何调整你的查询来让它做你想做的事情,但这应该让你走上正确的轨道。 ;-)

+0

这比选择进入#tmp drop table #tmp – relaj

+0

的解决方案要好得多,这肯定会起作用,但CTE往往更易于编写和理解。这就是为什么我非常喜欢他们。他们使用子查询也更有效率,因为它使得用额外的连接和查找无法获得奇怪的行为。 –