根据另一个表中行的存在来排序SELECT语句

时间:2016-11-28 15:31:14

标签: sql sql-server tsql

我有一个SELECT,其工作方式如下所示:

SELECT [AT].[Id], [AT].[Name] 
FROM [AT] 
WHERE [AT].[C] =@C 
ORDER BY [AT].[BOOST] DESC

[AT]是一张桌子。 [Boost]是一个计算的布尔值,因此当Boost为true时,这些项目将出现在列表的顶部。到目前为止这么容易。一切正常。

现在这里是一个棘手的问题,一些有希望的天才可以解决。 我希望[AT]。[BOOST]被替换为true / false,如果另一个SELECT从另一个表返回1个或多个记录说BT。因此,如果没有选择,则为false,如果选择了任何内容,则为真。 有问题的SELECT是:

Select [BT].[Id] 
From [BT] 
WHERE (DateTime.Now >= [BT].[SDate] 
 AND DateTime.Now <= [BT].[EDate]) 
 AND [BT].[SomeColumn] IS NOT NULL 
 AND [BT].[PVId]=[AT].[Id]

[BT]是另一张表。

这将使我摆脱冗余的[Boost],必须每天更新。

表[AT]将是:

[AT].Id  [AT].Name

1        Angela

2        Kate

3        Caroline

4        Mary

表[BT]将是:

[BT].Id  [BT].PVId [BT].SDate [BT].EDate [BT].SomeColumn

1        2         01/01/2012 01/02/2012 not Null

2        3         01/11/2016 31/12/2016 not Null

3        4         01/11/2016 31/12/2016 Null 


4        3         01/10/2016 08/10/2016 not Null  

DateTime.Now是29/11/2016 00:00:00

输出将是:

3        Caroline  
1        Angela  
2        Kate  
4        Mary  

所以所有人都会被选中,但Caroline会登顶,因为日期时间现在在SDate和EDate之间,而SomeColumn不是null。所有其他人都会出来我假设他们的索引顺序。基本上只有卡罗琳会得到提升,而且只会出现一次。

2 个答案:

答案 0 :(得分:0)

您可以使用联接来检查所需的BT值,然后根据它们的存在进行排序:

SELECT [AT].[Id], [AT].[Name] 
LEFT JOIN [BT] ON 
  [BT].[PVId]=[AT].[Id]
  AND (
    DateTime.Now >= [BT].[SDate] 
    AND DateTime.Now <= [BT].[EDate]
  ) 
  AND [BT].[SomeColumn] IS NOT NULL 
FROM [AT] 
WHERE [AT].[C] = @C 
ORDER BY (
  CASE WHEN [BT].[PVId] IS NOT NULL THEN 1 ELSE 2 END
)

ORDER BY子句使用BT.PVId的替换值,因为原始案例(Boost)是一个位值,因此查询不是按BT.PVId排序。如果这是可以接受的 - 假设不存在的值保留在结果集的末尾 - 那么您可以使用此ORDER BY:

ORDER BY [BT].[PVId] DESC

这必须是DESC,因为SQL Server的ORDER BY会在列表中首先放置空值。

如果你还没有BT.PVId,你会想要一个索引。

答案 1 :(得分:-1)

如果是Sql Server,那么你可以生成sql语法为nvarchar并使用sp_executesql执行它。 首先,您必须检查查询是否返回结果:

declare @order_column as nvarchar(100)
declare @statement as nvarchar(100)

set @order_column='default_order_value'
if exists
    (
    Select [BT].[Id] 
    From [BT] 
    WHERE (DateTime.Now >= [BT].[SDate] 
     AND DateTime.Now <= [[BT].[EDate]) 
     AND [BT].[SomeColumn] IS NOT NULL 
     AND [BT.PVId]=[AT].[Id]
     )
    set @order_column='some_val'

set @statement=
    'SELECT [AT].[Id] [AT].[Name] 
    FROM [AT] 
    WHERE [AT].[C] =@C 
    ORDER BY '+@order_column+' DESC'
Execute sp_executesql @statement;