tblUserProfile - 我有一个表格,其中包含所有个人资料信息(太多字段)
tblMonthlyProfiles - 另一个只包含ProfileID的表(想法是这个表包含2个profileids,有时会成为月度配置文件(在选择时))
现在,当我需要显示每月个人资料时,我只需从此tblMonthlyProfiles中选择并使用tblUserProfile加入以获取所有有效信息。
如果tblMonthlyProfile中没有行,则不会显示每月个人资料部分。
现在要求始终显示每月个人资料。如果monthlyProfiles中没有行,它应该从tblUserProfile中获取2个随机配置文件。如果monthlyProfiles中只有一行,它应该只从tblUserProfile中获取一个随机行。
在一个查询中执行所有这些操作的最佳方法是什么?
我觉得这样的事情
从tblUserProfile P中选择前2 * LEFT OUTER JOIN tblMonthlyProfiles M 关于M.profileid = P.profileid ORID by NEWID()
但是这总是从tblProfile给我2个随机行。我怎么解决这个问题?
答案 0 :(得分: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专栏是一种简单的方法,可以确保您尝试获得每月的第一个。
如果您可以控制表结构,只需在IsMonthlyProfile
表中添加一个布尔字段UserProfile
,就可以省去一些麻烦。然后是单个表查询order by IsBoolean, NewID()
答案 1 :(得分: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语句中,列的数量和类型必须匹配。