2013-05-22 7 views
3

Моя таблица имеет следующие данные,SQL Group по запросу для выбора данных из одной таблицы

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

Я хочу, чтобы выбрать строки (ID, имя, Девид) на основе следующих условий:

а. значение devID для имени abc было увеличено на 1, поэтому в результате должна отображаться только запись более высокого значения (только 102)

b. значение devID для имени def уменьшилось на 1, оно должно отобразить все записи (111 и 110)

Также мы будем продолжать добавлять записи для разных строк, и каждое имя будет не более 2 или max 3 строки в таблице, поэтому условие выше всегда должно быть истинным.

Пожалуйста, помогите мне по этому запросу. Спасибо заранее.

+0

Я использую SQL Server 2008 RDBMS – user2409235

+3

На основании ваших данных появится «ghi» в конечном результате? – Taryn

+0

Итак, ваш алгоритм состоит в том, что на основе последнего devID (если он больше или меньше), чем предыдущие идентификаторы dev, вы хотите повлиять на то, что возвращается. Можете ли вы еще объяснить, почему вы хотите все это сделать? –

ответ

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 Fiddle:http://www.sqlfiddle.com/#!3/b14513/18

Этот код вызывает только строки с DEVID больше (или равно) с последним вставленным DEVID кого-то с именем Name для отображения.

Результаты

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

Update (Запрос можно упростить далее):

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 

EDIT: Результаты:

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

Если я вас правильно понял, вы просто хотите получить последнее Девид (как показано ниже).

Так зачем с Присоединяется и прочее, если этот простой подход тоже работает:

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 
Смежные вопросы