2015-12-15 5 views
0

У меня есть следующие настройки:SQL, чтобы получить TOP ряды отдельной группы

ID | email_ID | email | priority 
--------------------------------------------------- 
1  1    [email protected]  2 
2  1    [email protected]  2 
3  1    [email protected]  2 
4  2    [email protected]  1 
5  2    [email protected]  1 
6  3    [email protected]  1 
7  4    [email protected]  1 

Я хочу, чтобы иметь возможность сказать, получить мне TOP 1000 строк, но мои результаты содержат только один email_ID и выводить в priorityпо возрастанию заказ.

я думал что-то вдоль линий:

select * from Table where email_ID in (select top 1 email_ID from Table group by email_ID) 

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

так, по первому зову я хотел бы получить

ID | email_ID | email | priority 
--------------------------------------------------- 
4  2    [email protected]  1 
5  2    [email protected]  1 

второй вызов:

ID | email_ID | email | priority 
--------------------------------------------------- 
6  3    [email protected]  1 

третий:

ID | email_ID | email | priority 
--------------------------------------------------- 
7  4    [email protected]  1 

четвёртых:

ID | email_ID | email | priority 
--------------------------------------------------- 
1  1    [email protected]  2 
2  1    [email protected]  2 
3  1    [email protected]  2 

Я хочу, чтобы получить партию до 1000 в то время, но каждая партия должна быть уникальной mail_ID и партии должны выйти в priority порядке (по возрастанию)

+0

Не могли бы вы показать нам ваш ожидаемый результат? –

+0

Можете ли вы как-то перефразировать то, что именно вы пытаетесь достичь? Ваш вопрос не совсем ясен. –

+0

более подробная информация добавлена. надеюсь, это поможет ! – scgough

ответ

0

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

у меня был думать и следующий будет гарантировать, что элементы вышли в желаемом порядке:

SELECT TOP 1000 t.* FROM [Table] t WHERE t.email_id IN (
    SELECT TOP 1 t2.email_id FROM [Table] t2 ORDER BY t2.priority 
) 

Моя таблица будет обрабатываться (до) 1000 записей в то время группирования результатов по email_id в priority заказ.

0

Я думаю, что вы можете сделать это с помощью функции кадрирования, если я правильно поняли вопрос.

-- Your sample data 
CREATE TABLE dbo.[table] 
(
    ID INT, 
    email_id INT, 
    email CHAR(7), 
    PRIORITY INT 
) 


INSERT INTO [table] VALUES (1,1,'[email protected]',2) 
INSERT INTO [table] VALUES (2,1,'[email protected]',2) 
INSERT INTO [table] VALUES (3,1,'[email protected]',2) 
INSERT INTO [table] VALUES (4,2,'[email protected]',1) 
INSERT INTO [table] VALUES (5,2,'[email protected]',1) 
INSERT INTO [table] VALUES (6,3,'[email protected]',1) 
INSERT INTO [table] VALUES (7,4,'[email protected]',1) 


SELECT 
    ID, 
    Email_id, 
    email, 
    priority 
FROM 
(SELECT *, ROW_NUMBER() OVER (PARTITION BY email_id ORDER BY PRIORITY ASC) AS RowNum FROM dbo.[table]) TableA 
WHERE RowNum <= 1000 
ORDER BY Priority ASC, ID ASC 
+0

это хорошо выглядит! я отдам его! – scgough

+0

его порядок правильно, но я хочу, чтобы вывести только партию из одного mail_id за звонок. идея заключается в том, что я создаю список получателей для отправки с помощью 'mail_id', а затем перехожу в следующий список получателей для следующего' mail_id' – scgough

+0

. Звучит так, как будто вам может понадобиться курсор для цикла, получить 1 email_id, отправить электронное письмо и т.п. – SQLChao

0

EDIT: Я читал этот вопрос еще раз и комментарий на другой ответ дал мне другое понимание того, что вы хотите. Этот последний запрос даст вам 1000 партий email_ID s, заказанных по приоритету.

select * from T where email_ID in (
    select top 1000 
     email_ID, min(priority) as priority 
    from T 
    group by email_ID 
    order by min(priority) 
) 

Оригинальный ответ следующим образом:

Я думаю, вы хотите что-то вроде этого. Но вам также нужны ID?

select top 1000 
    email_ID, min(email) as email, min(priority) as priority 
from T 
group by email_ID 
order by min(priority) 

Если вы то, возможно, это будет работать:

select top 1000 
    (
     select min(ID) from T t2 
     where t2.email_ID = t.email_ID and t2.priority = t1.priority 
    ) as ID, 
    email_ID, min(email) as email, min(priority) as priority 
from T t 
group by email_ID 
order by min(priority) 

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

Кроме того, если вы не можете иметь письма с различными приоритетами, то было бы проще просто вернуться min(ID) без подзапроса:

select top 1000 
    min(ID) as ID, email_ID, min(email) as email, min(priority) as priority 
from T 
group by email_ID 
order by min(priority) 

Я посмотрел на ваши вопросы и теперь видим, что email сек через тот же email_ID не идентичны.Я все еще подозреваю, что захват min(ID) и min(email) вытащит оба значения из одной и той же строки в вашем случае, но это было бы неверно в целом. Так что я думаю, что самый общий подход по этой дороге:

select 
    ID, email_ID, 
    (
     select min(email) from T te 
     where te.ID = tmin2.ID 
    ) as email, 
    priority 
from (
    select 
     min(ID) as ID, 
     email_ID, 
     min(t.priority) as priority as /* dummy aggregate */ 
    from 
     T t inner join 
     (
      select top 1000 email_ID, min(priority) as priority 
      from T 
      group by email_ID 
      order by priority 
     ) tmin 
      on tmin.email_ID = t.email_ID and tmin.priority = t.priority 
    group by t.email_ID 
) tmin2 

ли ваша версия SQL Server есть first_value()?

Возможно, на данный момент вы смущены: к сожалению, вам придется предоставить дополнительную информацию, чтобы отсортировать некоторые из этих беспорядков.

Смежные вопросы