2016-07-22 72 views
2

加入三个表场景... STORE获取LIST。 'LIST'基本上是需要计数的商店库存SKU的集合。如何使用NOT IN CLAUSE

当商店从指定给它的给定List开始计数SKU时,信息被保存在另一个名为'StoreCycles'的表中,该表记录了ListId,StoreName和计数开始和完成的日期。

这些是我的表格。

表1中。表与“词典”,其具有一个主键“ListId”

ListId ListName 
    1  abc 
    2  def 
    3  ghi 

表2“商店” - 从上面的表中的每个列表(“列表”表)被分配给一个或多个商店。 “商店”表中的ListId是“列表”表格的主键。 Listid和LineId一起组成外键。

ListId LineId StoreName 
    1  1 StoreA 
    1  2 StoreD 
    2  1 StoreB 
    2  2 StoreC 
    2  3 StoreA 
    3  1 StoreA 

表3.'StoreCycles' - 当分配给商店的列表开始计数并完成时,它会保存。

ListId StoreName StartDate CompleteDate 
    1  StoreA 2016-7-22 2016-7-22 
    2  StoreA 2016-7-22 
    2  StoreC 2016-7-22 

在任何时候我想拉起那些尚未完成的名单,即他们有一个空的完整日期。

这是我的查询:

Select T0.ListId, 
T0.ListNaame , 
T2.StartDate 
From Lists T0 
JOIN Stores T1 On T0.ListId = T1.ListId 
LEFT JOIN StoreCycles T2 ON T0.ListId = T2.ListId 
WHERE T1.StoreName = 'StoreA' 
AND T0.ListId NOT IN (SELECT ListId FROM StoreCycles WHERE CompleteDate IS NOT NULL) 

结果应该是>>

ListId ListName StartDate 
    2  def  2016-7-22 
    3  ghi  NULL 

但我得到的是这种

ListId ListName StartDate 
2  def  NULL 
2  def  NULL 
3  ghi  NULL 
+0

你在结果集中有字段'ListName'作为整数,但是你的数据显示字段是'abc'。请更正您的问题,以显示您想查询的结果:“LineId”或“ListName” – Tony

+1

我试过了您的查询,它给出了应该的结果。至少如果CompleteDate是日期字段。你能否检查一下,如果CompleteDate不是一些带空格的varchar,那里应该是null的? – LukStorms

+0

我也试过了你的查询(http://sqlfiddle.com/#!9/913ce/2),它给出的结果与你所期望的相似 - 虽然列表_name_与你在例子中给出的_id不同。 – Tony

回答

1

只是路过,并转储SQL。

继续,没什么可看的。

这里没有找寻错误。

declare @Lists table (ListId int primary key, ListName varchar(20)); 
insert into @lists values (1,'abc'),(2,'def'),(3,'ghi'); 

declare @Stores table (ListId int, LineId int, StoreName varchar(20)); 
insert into @Stores values 
(1,1,'StoreA'), 
(1,2,'StoreD'), 
(2,1,'StoreB'), 
(2,2,'StoreC'), 
(2,3,'StoreA'), 
(3,1,'StoreA'); 

declare @StoreCycles table (ListId int, StoreName varchar(20), StartDate date, CompleteDate date); 
insert into @StoreCycles values 
(1,'StoreA','2016-7-22','2016-7-22'), 
(2,'StoreA','2016-7-22',null), 
(2,'StoreC','2016-7-22',null); 

SELECT 
L.ListId, 
L.ListName, 
SC.StartDate 
FROM @Stores S 
JOIN @Lists L On (S.ListId = L.ListId) 
LEFT JOIN @StoreCycles SC ON (S.ListId = SC.ListId AND S.StoreName = SC.StoreName) 
WHERE S.StoreName = 'StoreA' 
AND SC.CompleteDate IS NULL; 
+0

如果您发现结果检索ListId引用ListId'2'它被分配给的两个条目,我已编辑您的小提琴在这里[链接](http://sqlfiddle.com/#!9/ddf001/1)都StoreA和StoreC。我只想拉一个特定的商店的结果。 – Harrobbed

+0

这次我将Storename添加到第二次加入。获取预期的结果。 – LukStorms

+0

非常感谢你。我真的需要磨练我的SQL技能。感谢所有花时间帮助我的人,即使我没有正确地设定问题,这是第一次。 – Harrobbed

0

也许另一种方式来看待它的结果将返回StartDate为NULL(无记录)或CompleteDate为NULL(NULL)的所有行不完整的记录)。另外,如果外键使用2列,则可能需要在JOIN中使用两列。

SELECT T0.ListId, 
     T0.ListName, 
     T2.StartDate 
FROM Lists T0 
      JOIN Stores T1 
       ON T1.ListId = T0.ListId 
      LEFT JOIN StoreCycles T2 
       ON T2.ListId = T1.ListId 
       AND T2.LineId = T1.LineId 
WHERE T1.StoreName = 'StoreA' 
AND (T2.CompleteDate IS NULL OR T2.StartDate IS NULL) 
0
Select 
    l.ListId 
    ,l.ListNaame 
    ,sc.StartDate 
From 
    Lists l 
    JOIN Stores s 
    ON l.ListId = s.ListId 
    AND s.StoreName = 'StoreA' 
     LEFT JOIN StoreCycles sc 
     ON s.ListId = sc.ListId 
     AND s.LineId = sc.LineId 
WHERE 
     sc.CompleteDate IS NULL 

你已经在做连接,如果你正确地建立他们,你将不需要选择或不在您的where子句。你的StoreCycles的关系似乎是错误的,因为你试图从Lists直接去StoreCyclesStores是中间表。

还只是一个想法,为什么不使用表的别名,这将有助于你知道你是指什么表,而不是T0,T1,T2,如L,S,SC ....