2017-07-19 36 views
1

我有一个SQLite3数据库与我需要通过几个因素过滤的表。一旦这样的因素是根据同一个表内的其他行的内容来过滤我们的行。嵌套的SQL查询与自加入 - 如何筛选行OUT

从我研究过,自己JOIN将被要求,但我不知道我会怎么做,以过滤表的几个因素。

下面是数据的一个示例表:

Name Part # Status Amount 
---------------------------------   
Item 1 12345 New  $100.00 
Item 2 12345 New  $15.00 
Item 3 35864 Old  $132.56 
Item 4 12345 Old  $15.00 

我需要做的是找到任何Item S作相同Part #,其中一人有一个“老” StatusAmount是相同。

因此,首先我们得到所有具有Part #“12345”的行,然后检查是否有任何行具有匹配Amount的“旧”状态。在这个例子中,我们会有Item2Item4

现在需要做的是返回表格中具有“新”Status的行的REST,基本上丢弃这两个项目。

所需的输出:

Name Part # Status Amount 
---------------------------------   
Item 1 12345 New  $100.00 

删除了所有“老”的状态行,并且有一个匹配的“零件编号”和“量”与“旧”状态的任何“新”。(对不起,我知道这很混乱,因此我需要帮助)。

我已经研究了以下资源,试图自己弄清楚这一点,但有很多层次让我感到困惑。

涉及同一表中的列进行比较的前两个链路。第三个似乎是一个非常相似的问题,但没有可读的答案(对我来说,无论如何)。

我也在做Java开发,这样做会很简单,但如果可能的话,我希望单个SQL查询(嵌套)。

+2

你可以提供一个样本预期产出以澄清你希望发生的事情? – yanman1234

+0

在你的例子中你想要项目3?它没有“新”记录,但它确实有旧的记录。你似乎并没有指出“删除所有”OLD“状态行以及任何与之相匹配的新行为......”@ p1erstef有很好的回应IMO它肯定是occam剃须刀的答案:P – xQbert

+0

换句话说......想你想看所有新零件的旧名称没有相应的价格和零件号。 – xQbert

回答

0

这是一个T-SQL的答案。希望它是可翻译的。如果你有一个大数据集的比赛,你可能会改变不存在!存在。

select * 
from table 
where Name not in(
      select Name 
      from table t1 
      join table t2 
       on t1.PartNumber = t2.PartNumber 
       AND t1.Status='New' 
       AND t2.Status='Old' 
       and t1.Amount=t2.Amount) 
and Status = 'New' 
0

试图了解你要尽我所能的...

SELECT DISTINCT yt.PartNum, yt.Status, yt.Amount 
FROM YourTable yt 
JOIN YourTable yt2 
    ON yt2.PartNum = yt.PartNum 
AND yt2.Status = 'Old' 
AND yt2.Amount != yt.Amount 
WHERE yt.Status = 'New' 

这使得与具有不同的价格的老状态的新状态的一切。

+0

我认为实际需要匹配的数量(=,不是!=),您的“join”需要是“left”连接,where子句需要“yt2.partNum为null”。你想要哪里的旧的匹配partnum新的和价格匹配的地方,你有一个新的部分W/O旧的匹配。 – xQbert

0

可以使用肠子加入组合选择的状态取得老不仅如此

select * from 
my_table 
INNER JOIN (
    select 
     Part_# 
     , Amount 
     , count(distinct Status) 
     , sum(case when Status = 'Old' then 1 else 0) 
    from my_table 
    group part_#, Amount, 
    having count(distinct Status)>1 
    and sum(case when Status = 'Old' then 1 else 0) > 0 
) t on.t.part_# = my_table.part_# 
    and status = 'new' 
    and my_table.Amount <> t.Amount 
2

的“不存在” statment应该做的伎俩:

select * from table t1 
where t1.Status = 'New' 
and not exists (select * from table t2 
    where t2.Status = 'Old' 
    and t2.Part = t1.Part 
    and t2.Amount = t1.Amount); 
+0

尽管select *可以选择1或列名,但似乎效率最高。 *在内存/性能上看起来过度杀伤;但是再一次,也许引擎很聪明,可以忽略选择,因为没有使用它。 – xQbert

+0

@xQbert数据库确实会忽略EXISTS中的列;它检查*行*,而不是列值。 (这就是为什么[这是'SELECT *'实际上是一个好主意的唯一地方](https://stackoverflow.com/documentation/sql/9843/clean-code-in-sql/30300/select)。) –