查询从一个表中获取行,否则从另一个表中获取随机行

时间:2010-03-25 14:35:04

标签: tsql

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个随机行。我怎么解决这个问题?

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语句中,列的数量和类型必须匹配。

相关问题