想象以下具有最小值(一些列的)的行:选择根据WHERE子句
我有一个表Customers
,每个客户可以有0个或多个PhoneNumbers
。电话号码在Customers
'CusId
及其自己的ListIx
(因此(CusId, ListIx)
)上索引。
我想选择一个客户名单及其第一个(min(ListIx)
)电话号码。
问题,这样做最优雅的方法是什么?
例如:
select
c.FirstName, c.LastName, pn.PhoneNo
from Customers c
left join PhoneNumbers pn
on c.CusId = pn.CusId
and pn.ListIx = (select min(ListIx) from PhoneNumbers where CusId = c.CusId)
这工作,但在这个例子中,WHERE
条款和JOIN
s为很简单。
但想象一个更复杂的例子:
while 1=1 begin
select
-- Combine all phone numbers along with their type into one string
@PhoneComp = @PhoneComp + ' ' + PhoneNo
+ case when PhTp is not null then '/' + PhTp end,
@ListIx = p.ListIx
from PhoneNumbers
where
CusId = @CusId and ListIx > @ListIx and
ListIx = (select min(ListIx) from PhoneNumbers where CusId = @CusId and ListIx > @ListIx)
end
即使它被简化,但我担心的子查询可能变得过于复杂。
你看,Sybase ASE的,以下是可能的:
while 1=1 begin
select
-- Combine all phone numbers along with their type into one string
@PhoneComp = @PhoneComp + ' ' + PhoneNo
+ case when PhTp is not null then '/' + PhTp end,
@ListIx = p.ListIx
from PhoneNumbers
where
CusId = @CusId and ListIx > @ListIx
having
CusId = @CusId and ListIx > @ListIx and ListIx = min(ListIx)
end
即使这样,当你真的想想,它没有任何意义,但你知道这意味着什么(和所以Sybase很幸运)。但是,代码得到MS SQL Server的抱怨:
Column 'PhoneNumbers.CusId' is invalid in the HAVING clause because it is not contained in either an aggregate function or the GROUP BY clause.
Column 'PhoneNumbers.ListIx' is invalid in the HAVING clause because it is not contained in either an aggregate function or the GROUP BY clause.
你可能会问,为什么是HAVING
子句中基本上重复了WHERE
条款?这是因为在存在HAVING
子句时,Sybase ASE会忽略WHERE
子句。
例如Sybase ASE中:
select
ListIx, PhoneNo
from PhoneNumbers
where
CusId = @CusId
having
ListIx=min(ListIx)
会得到具有最低ListIx,不管客户(@CusId
)的所有电话号码。编辑:我应该提到,通过添加group by CusId
的结果如预期的那样,但Sybase ASE甚至允许这样的事实值得怀疑。
我在这里提到Sybase ASE,因为我正在转换很多旧的Sybase ASE SQL代码以便与MS SQL Server一起使用。虽然子查询确实有效,但我确实怀疑我是否缺少一些明显的解决方案。
搜索ROW_NUMBER的计算器。 ROW_NUMBER()OVER(PARTITION BY CustId ORDER BY ListIx desc)r(..)其中r = 1(对于MSSQL,即sybase加入子查询时由CustId以min(ListIx)组) – mxix 2014-12-19 11:03:16
@mxix:不是Sybase 15.x应该有'ROW_NUMBER()'?尽管这是一个有趣的解决方案,但我担心子查询将成为我现在使用的,以确保代码在Sybase和MS SQL中都能正常工作。 – Svip 2014-12-19 11:06:33
我不太了解Sybase。只是想指出一个交叉的数据库解决方案。如果sybase也有ROW_NUMBER试试看,那么它是一个简单的解决方案。 – mxix 2014-12-19 11:21:53