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

Tsql 查询以从一个表中获取行,否则从另一个表中获取随机行,tsql,Tsql,tblUserProfile-我有一个表,其中包含所有配置文件信息(字段太多) TBLMonthyprofiles-另一个表中只有ProfileID(其想法是此表包含2个ProfileID,有时会成为月度概要文件(在选择时)) 现在,当我需要显示每月配置文件时,我只需从这个tblMonthlyProfiles中进行选择,并加入tblUserProfile以获取所有有效信息 如果tblMonthlyProfile中没有行,则不显示每月配置文件部分 现在的要求是始终显示每月概要文件。如果Monthl

tblUserProfile-我有一个表,其中包含所有配置文件信息(字段太多)

TBLMonthyprofiles-另一个表中只有ProfileID(其想法是此表包含2个ProfileID,有时会成为月度概要文件(在选择时))

现在,当我需要显示每月配置文件时,我只需从这个tblMonthlyProfiles中进行选择,并加入tblUserProfile以获取所有有效信息

如果tblMonthlyProfile中没有行,则不显示每月配置文件部分

现在的要求是始终显示每月概要文件。如果MonthlyProfile中没有行,它应该从tblUserProfile中选择2个随机配置文件。如果MonthlyProfile中只有一行,它应该只从tblUserProfile中随机选取一行

在一个查询中完成这一切的最佳方法是什么

我是这样想的

从tblUserProfile p中选择前2* 左外连接TBL每月配置文件M 在M.profileid=P.profileid上 NEWID()命令


但这总是给我tblProfile中的两个随机行。我怎样才能解决这个问题

试试这样的方法:

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到4条记录。抓住前两个。FinalOrder专栏是一个简单的方法,可以确保您尝试获得每月的第一个


如果您可以控制表结构,只需在
UserProfile
表中添加一个布尔字段
ismonthyprofile
,就可以省去一些麻烦。然后是一个单表查询,
orderbyisboolean,NewID()

尝试以下操作:

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到4条记录。抓住前两个。FinalOrder专栏是一个简单的方法,可以确保您尝试获得每月的第一个


如果您可以控制表结构,只需在
UserProfile
表中添加一个布尔字段
ismonthyprofile
,就可以省去一些麻烦。然后它是一个单表查询,
orderbyisboolean,NewID()

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

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

我进一步研究它时,我认为第二个SELECT不需要再次连接到monthly表。但无论如何,我希望你能理解。但是在这个问题中,随机的东西去了哪里?Profiles表有数百条记录,我只需要任意两行随机数据。第二个查询应该有NEWID()随机化器。已编辑。正在获取此错误。如果语句包含UNION、INTERSECT或EXCEPT运算符,则ORDER BY项必须出现在选择列表中。确定,因此请确保显式选择每个字段名(而不是像我在本例中所做的那样使用SELECT*。并确保顶部最外层的SELECT包含FinalOrder。我进一步查看它时,我认为第二个SELECT不需要再次连接到monthly表。但无论如何,我希望您能理解。但是在这个查询中,随机的东西去了哪里?Profiles表有数百个记录,我只需要任意2个随机行。第二个查询应该有NEWID()随机化器。编辑它。获取此错误。如果语句包含UNION、INTERSECT或EXCEPT运算符,则ORDER BY项必须出现在选择列表中。确定,因此确保显式选择每个字段名(而不是像我在本例中那样使用SELECT*。并确保顶部最外面的SELECT包含FinalOrder。