Получение почти четких строк - PullRequest
0 голосов
/ 01 февраля 2011

У меня есть такая таблица

C1             C2            C3
Mike           London        578
Mike           Bonn          578
Jane           Madrid        245
Billy          Paris         345
Jane           Rome          245

И мне нужен запрос, который дает мне:

C1             C2            C3
Mike           London        578
Jane           Madrid        245
Billy          Paris         345

То есть запрос, который дает мне что-то вроде отличного в C1, игнорируя следующие вхождения того же значения в C1.

РЕДАКТИРОВАТЬ: Пожалуйста, извините, это был просто быстрый пример, и некоторые из вас, кажется, побуждают некоторых из вас думать, что C3 имеет значение, я редактирую его, чтобы он выглядел как настоящая таблица, которая имеет около 50 столбцов и проблемные строки все идентичны, за исключением значения, которое можно отбросить.

Ответы [ 4 ]

1 голос
/ 01 февраля 2011

Если вам не важно, из какой записи находятся данные, вы можете просто записать их как:

SELECT C1, min(C2), min(C3)
FROM table
GROUP BY C1

Проблема здесь в том, что min (C2) и min (C3) могут фактически смешивать данныеиз разных записей.

Если бы у вас был первичный ключ, вы могли бы легко избежать идентификатора:

SELECT C1, C2, C3
FROM table t
WHERE id IN (
  SELECT min(t2.id) 
  FROM table t2
  GROUP BY t2.C1)
1 голос
/ 01 февраля 2011

На самом деле в SQL нет такого простого понятия, как «следующие вхождения», потому что множества / отношения по умолчанию неупорядочены .Вы должны явно указать порядок упорядочения строк с помощью предложения ORDER BY, а затем выбрать из этого упорядоченного отношения нужную вам строку или строки (используя TOP в SQL Server 2000).Похоже, вы не сортируете по убыванию C3 (поскольку у Джейн 346, а вы хотите ее 245).Какой неявный порядок подразумевается в вашем слове «следующий» (т. Е. Вы хотите, чтобы первая строка на отдельного человека)?Как вы хотите определить first в этом запросе?Вы хотите, чтобы у каждого человека было самое низкое значение C3?Если это так, вы можете сгруппировать по человеку, взяв мин (с3) во встроенном представлении и присоединить это встроенное представление к другому встроенному представлению, где вы выбрали отдельный C1.

0 голосов
/ 01 февраля 2011

Скорее всего, я глупый, но различный принимает четкую комбинацию всех столбцов в выборке.

Чтобы добиться этого, вам понадобится больше данных, что-то, чтобы определить, какая строка была первой.

Вот код, который я взбил ...

DECLARE @TBL TABLE(

    ID INT IDENTITY(1,1),
    C1 VARCHAR(100),
    C2 VARCHAR(100),
    C3 INT

)
INSERT INTO @TBL VALUES ('Mike','London',578)
INSERT INTO @TBL VALUES ('Mike','Bonn',234)
INSERT INTO @TBL VALUES ('Jane','Madrid',245)
INSERT INTO @TBL VALUES ('Billy','Paris',345)
INSERT INTO @TBL VALUES ('Jane','Rome',346)

SELECT * FROM @TBL T
WHERE
ID = (SELECT MIN(ID) FROM @TBL CHILD WHERE CHILD.C1 = T.C1)
GROUP BY ID,C1,C2,C3

Надеюсь, это поможет?

0 голосов
/ 01 февраля 2011

Используйте RANK () OVER PARITION, как это (2005, 2008):

declare @table  as table (c1 nvarchar(10), c2 nvarchar(10), c3 int, id int identity(1,1))

insert into @table values
('Mike',           'London',        578),
('Mike',           'Bonn',          234),
('Jane',           'Madrid',        245),
('Billy',          'Paris',         345),
('Jane',           'Rome',          346)

select c1, c2, c3 from 
( select id, c1, c2, c3, RANK() over ( partition by c1 order by id) as Rank from @table) tmp
where tmp.Rank = 1
order by id 

Используйте интересное предложение WHERE, как это (2000):

select t2.*
from
@table t2
where 
(select COUNT(*) from @table t where t.c1=t2.c1 and (t2.c2 > t.c2 or (t2.c2 = t.c2 and t2.c3 > t.c3))) = 1
union
select * from @table where c1 in (select c1 from @table group by c1 having COUNT(*) = 1)

Порядокотличается от вышеупомянутого, но вам придется разобраться с этим в ваших данных реального мира.

...