2013-05-22 62 views
3

選擇數據我的表有以下數據,SQL集團通過查詢,從同一個表

ID name devID 
1 abc 101 
2 def 111 
3 ghi 121 
4 abc 102 
5 def 110 

我想選擇的行(ID,姓名,DEVID)基於以下條件:

一個。名稱abc的devID值已增加1,因此只有更高的值記錄應顯示在結果中(僅限於102)

b。名稱def的devID值已經減少1,它應該顯示所有記錄 (111和110)

此外,我們將繼續添加不同行的記錄,每個名稱不會超過2或表中最多3行,所以上述條件應始終爲真。

請幫我看看這個查詢。 在此先感謝。

+0

我正在使用sql server 2008 RDBMS – user2409235

+3

根據你的數據'ghi'會出現在最終結果中嗎? – Taryn

+0

因此,您的算法是基於最後一個devID(如果它大於或小於)前一個dev ID,則您想要影響返回的內容。你能更好地解釋一下爲什麼你想要做這些嗎? –

回答

1

以下應該可以幫助你解決你的問題,如果我理解正確你的問題:

SELECT * 
FROM table_data AS a 
WHERE a.devid >= 
    (SELECT DEVID 
    FROM table_data AS C 
    WHERE c.ID = 
     (SELECT max(b.ID) 
      FROM table_data AS b 
      GROUP BY b.name HAVING b.name = a.name)) ; 

SQL小提琴:http://www.sqlfiddle.com/#!3/b14513/18

此代碼只會導致DEVID的行數大於(或等於),並顯示名爲Name的人的最後一個插入的DEVID

結果

ID NAME DEVID 
2 def  111 
3 ghi  121 
4 abc  102 
5 def  110 

更新(查詢可以進一步簡化爲):

SELECT * 
FROM table_data AS a 
WHERE a.devid >= 
    (SELECT DEVID 
    FROM table_data AS C 
    WHERE c.ID = 
     (SELECT max(b.ID) 
      FROM table_data AS b 
      where b.name = a.name)) ; 

另外索引應放置在ID和DEVID。

2

我使用了一種增量方法。我真的沒有看到另一種選擇。這將返回你需要什麼,我相信:

create table #t1 
(
    ID int identity, 
    name varchar(3), 
    devID int 
) 

insert into #t1(name,devID) 
values('abc',101),('def',111),('ghi',121),('abc',102),('def',110) 


create table #t2 
(
    ID int, 
    name varchar(3), 
    devID int 
) 

declare @count int = 1, 
    @name1 varchar(3) 
while @count <= (select MAX(ID) from #t1) 
begin--1 
    set @name1 = (select name from #t1 where ID = @count) 
    if (@name1 not in (select distinct name from #t2)) or ((select devID from #t1 where ID = @count) < (select devID from #t2 where name = @name1)) 
    begin--2 
     insert into #t2 
      select * 
      from #t1 
      where ID = @count 
    end--2 
    else 
    begin--2 
     update #t2 
      set devID = (select devID from #t1 where ID = @count) 
      where name = @name1 
    end--2 

    set @count+=1 
end--1 

select * 
from #t2 

drop table #t1 
drop table #t2 

編輯:結果:

ID   name devID 
----------- ---- ----------- 
1   abc 102 
2   def 111 
3   ghi 121 
5   def 110 

(4 row(s) affected) 
2

使用INNER JOIN本身和UNION結果可能是一個好方法。

SQL Fiddle

/* select all rows that match criteria A */ 
SELECT d2.ID, d2.name, d2.devID 
FROM data d1 
     INNER JOIN data d2 ON d2.devID = d1.devID + 1 
          AND d2.ID > d1.ID 
UNION 
/* select first rows that match criteria B */ 
SELECT d1.ID, d1.name, d1.devID 
FROM data d1 
     INNER JOIN data d2 ON d2.devID = d1.devID - 1 
          AND d2.ID > d1.ID 
UNION 
/* select second rows that match criteria B */ 
SELECT d2.ID, d2.name, d2.devID 
FROM data d1 
     INNER JOIN data d2 ON d2.devID = d1.devID - 1 
          AND d2.ID > d1.ID 
+0

您的解決方案可以正常工作,但是您會過濾出名爲'GHI'的條目,這會導致缺少一行。請參閱:http://www.sqlfiddle.com/#!3/b14513/20 –

+0

+1,以獲得快速結果。您的查詢的工作速度比使用嵌套查詢要快得多。 –

+0

@meewoK - 我知道,但不清楚它是否應該在結果中*(見bluefeet的評論)*。 –

2

如果我理解正確的,你只是想獲得最新的DEVID(如下圖所示)。

那麼何必用,如果這個簡單的方法有效連接和東西,太:

SELECT DISTINCT(Name), (SELECT TOP 1 devID FROM Table t2 
WHERE t2.Name=t1.Name Order By ID desc) FROM table t1 

你的記錄:

ID name devID 
1 abc 101 
2 def 111 
3 ghi 121 
4 abc 102 
5 def 110 

您預期的結果(也有小提琴手檢查)

name devID 
ghi 121 
abc 102 
def 110