如何检查一个搜索与另一个搜索是否缺失行?

问题描述:

我有一个表相关列是:如何检查一个搜索与另一个搜索是否缺失行?

CREATE TABLE [dbo].[PrmsBlotter](
    [ID] [int] IDENTITY(1,1) NOT NULL, 
    [BBox] [varchar](250) NOT NULL, 
    [RunDateStart] [datetime] NOT NULL, 
    [RunType] [varchar](50) NOT NULL, 
    [TestDateFrom] [date] NULL, 
    ... 
) 

BBOX是黑匣子的名字。 RunType可以是Live或Backtesting。每次实时运行都会得到一个backtest,以便backtest的TestDateFrom等于Live测试的RunDateStart。

我需要知道是否有任何实时运行没有匹配的回测。我至今:

SELECT t1.BBox, t1.dd, t2.BBox, t2.dd FROM 
(SELECT BBox, CONVERT(date,RunDateStart) as dd FROM [PrimusGroup].[dbo].[PrmsBlotter] 
WHERE RunType = 'Live') t1 
LEFT JOIN 
(SELECT BBox, CONVERT(date,TestDateFrom) as dd FROM [PrimusGroup].[dbo].[PrmsBlotter] 
WHERE RunType = 'Backtesting') t2 
ON (t1.BBox = t2.BBox AND t1.dd = t2.dd) 

我加入两个查询一个生命,一个用于backtests和BBOX的名字加入他们相等,生活的rundatestart等于回溯测试的testdatefrom。这就是我卡住的地方。我不知道如何说没有匹配的地方。

有没有办法做到这一点?

使用not exists()与没有相应'Backtesting'匹配BBoxTestDateFromRunDateStart返回'Live'测试:

select 
    t.BBox 
    , convert(date, t.RunDateStart) as dd 
from [PrimusGroup].[dbo].[PrmsBlotter] t 
where t.RunType = 'Live' 
    and not exists (
    select 1 
    from [PrimusGroup].[dbo].[PrmsBlotter] i 
    where i.RunType = 'Backtesting' 
     and i.BBox = t.BBox 
     and convert(date,i.TestDateFrom) = convert(date,t.RunDateStart) 
) 
+0

什么选择1的意思是? – bkarj

+0

'select 1'并不意味着什么,因为exists()和not exists()并不实际返回任何列。这与在此上下文中选择*或选择空值相同。当使用exists()时,'select 1'和'select *'之间没有** runtime **性能差异。尽管使用'select 1'将避免在查询编译期间检查该表的任何不需要的元数据。 [EXISTS子查询:SELECT 1与SELECT * - Conor Cunningham](http://www.sqlskills.com/blogs/conor/exists-subqueries-select-1-vs-select/) – SqlZim

你需要一个WHERE条款:

SELECT l.BBox, l.rdday, bt.BBox, bt.btday FROM 
FROM (SELECT BBox, CONVERT(date, RunDateStart) as rdday 
     FROM [PrimusGroup].[dbo].[PrmsBlotter] 
     WHERE RunType = 'Live' 
    ) l LEFT JOIN 
    (SELECT BBox, CONVERT(date, TestDateFrom) as btday 
     FROM [PrimusGroup].[dbo].[PrmsBlotter] 
     WHERE RunType = 'Backtesting' 
    ) bt 
    ON l.BBox = bt.BBox AND l.rtday = bt.btday 
WHERE bt.BBox IS NULL; 

注:dd是一列一个不好的名字,因为它是用于datepart()功能的关键字。

我想你也可以用group byhaving做到这一点:

SELECT BBox, CONVERT(date, RunDateStart) as rdday 
FROM [PrimusGroup].[dbo].[PrmsBlotter] 
WHERE RunType IN ('Live', 'BackTesting') 
GROUP BY BBox, CONVERT(date, RunDateStart) 
HAVING SUM(CASE WHEN RunType = 'Live' THEN 1 ELSE 0 END) > 0 AND 
     SUM(CASE WHEN RunType = 'BackTesting' THEN 1 ELSE 0 END) = 0 ;