想象以下具有最小值(一些列的)的行:選擇根據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