2017-07-19 59 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)。) –