2010-03-25 64 views
1

tblUserProfile得到行,否則隨機行 - 我有持有的所有資料信息(太多字段)的表查詢到從一個表從另一個

tblMonthlyProfiles - 它只有在它的簡檔(在另一個表想法是,這個表擁有2個有時成爲月度配置文件(選擇)的配置文件)

現在,當我需要顯示每月配置文件時,我只需從這個tblMonthlyProfiles做一個選擇,並加入tblUserProfile以獲得所有有效的信息。

如果tblMonthlyProfile中沒有行,則不顯示月度配置文件部分。

現在的要求是總是顯示月度配置文件。如果monthlyProfiles中沒有行,它應該從tblUserProfile中選取兩個隨機配置文件。如果monthlyProfiles中只有一行,它應該只從tblUserProfile中選取一個隨機行。

在單個查詢中完成所有這些操作的最佳方法是什麼?

我覺得這樣的事情

從tblUserProfile P LEFT OUTER JOIN tblMonthlyProfiles中號 上M.profileid = P.profileid ORDER BY NEWID()

選擇頂部2 *但是,這總是給我來自tblProfile的2個隨機行。我該如何解決這個問題?

回答

1

嘗試這樣:

SELECT TOP 2 Field1, Field2, Field3, FinalOrder FROM 
(
select top 2 Field1, Field2, Field3, FinalOrder, '1' As FinalOrder from tblUserProfile P JOIN tblMonthlyProfiles M on M.profileid = P.profileid 
UNION 
select top 2 Field1, Field2, Field3, FinalOrder, '2' AS FinalOrder from tblUserProfile P LEFT OUTER JOIN tblMonthlyProfiles M on M.profileid = P.profileid ORDER BY NEWID() 
) 
ORDER BY FinalOrder 

的想法是要選擇兩個月度概況(如果存在的很多),然後2個隨機配置文件(如你正確地做),然後UNION它們。在那時您將有2到4條記錄。搶到前兩名。 FinalOrder專欄是一種簡單的方法,可確保您每月都能獲得第一份。

如果您擁有對錶結構的控制權,只需在UserProfile表中添加一個布爾字段IsMonthlyProfile即可節省一些麻煩。那麼它是一個單表查詢,order by IsBoolean, NewID()

+0

正如我進一步看到它,我不認爲第二個SELECT需要再次加入到月度表。但無論如何,我希望你明白這個主意。 – LesterDove 2010-03-25 14:50:14

+0

但在這個查詢中,隨機事件發生在哪裏?配置文件表有數百條記錄,我只需要任意2個隨機行。 – 2010-03-25 14:50:55

+0

第二個查詢應該有NEWID()隨機數發生器。編輯它。 – LesterDove 2010-03-25 14:52:57

0

在SQL 2000+符合語法,你可以這樣做:

Select ... 
From (
     Select TOP 2 ... 
     From tblUserProfile As UP 
     Where Not Exists(Select 1 From tblMonthlyProfile As MP1) 
     Order By NewId() 
     ) As RandomProfile 
Union All 
Select MP.... 
From tblUserProfile As UP 
    Join tblMonthlyProfile As MP 
     On MP.ProfileId = UP.ProfileId 
Where (Select Count(*) From tblMonthlyProfile As MP1 ) >= 1 
Union All 
Select ... 
From (
     Select TOP 1 ... 
     From tblUserProfile As UP 
     Where (Select Count(*) From tblMonthlyProfile As MP1 ) = 1 
     Order By NewId() 
     ) As RandomProfile 

使用SQL 2005+ CTE你可以這樣做:

With 
    TwoRandomProfiles As 
    (
    Select TOP 2 ..., ROW_NUMBER() OVER (ORDER BY UP.ProfileID) As Num 
    From tblUserProfile As UP 
    Order By NewId() 
    ) 
Select MP.Col1, ... 
From tblUserProfile As UP 
    Join tblMonthlyProfile As MP 
     On MP.ProfileId = UP.ProfileId 
Where (Select Count(*) From tblMonthlyProfile As MP1 ) >= 1 
Union All 
Select ... 
From TwoRandomProfiles   
Where Not Exists(Select 1 From tblMonthlyProfile As MP1) 
Union All 
Select ... 
From TwoRandomProfiles 
Where (Select Count(*) From tblMonthlyProfile As MP1 ) = 1 
    And Num = 1 

的CTE有隻查詢一次隨機配置文件和使用ROW_NUMBER()列的優點。

顯然,在所有UNION語句中,列的數量和類型必須匹配。