我有一个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。所有其他人都会出来我假设他们的索引顺序。基本上只有卡罗琳会得到提升,而且只会出现一次。
答案 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;