2013-05-22 63 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