2015-07-29 6 views
1

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

Таблица: Testing

create table testing 
(
    colnum varchar(10), 
    coldate date, 
    colid int 
); 

Вставка: создание

insert into testing values('111','2015-01-01',1); 
insert into testing values('111','2015-01-02',1); 
insert into testing values('111','2015-01-03',1); 
insert into testing values('111','2015-01-04',1); 
insert into testing values('111','2015-01-05',1); 
insert into testing values('222','2015-01-01',1); 
insert into testing values('333','2015-01-01',1); 

Index :

create clustered index id_idx on testing(colid); 
create nonclustered index date_nidx on testing(coldate); 
create nonclustered index num_nidx on testing(colnum); 

Примечание: Теперь я хочу показать записи, которые являются только в конкретной даты и конкретного идентификатора, а не другой даты.

Например: Я хочу показать записи, которые являются ТОЛЬКО В указанной дате и ID, но не в других датах.

Учитывая Дата: 2015-01-01
Учитывая ID: 1

Для которого я написал следующий запрос:

select * from testing 
where coldate in ('2015-01-01') 
     and coldid = 1 
     and colnum not in(select colnum from testing where coldid = 1 and 
         coldate in('2015-01-02','2015-01-03','2015-01-04' 
          '2015-01-05'); 

Результат:

colnum coldate  colid 
-------------------------- 
222  2015-01-01 1 
333  2015-01-01 1 

Explaination: Запрос показывает два поскольку обе записи имеют только конкретная дата и идентификатор Но запись 111 не показана, потому что это также относится к другим датам, как вы можете видеть в приведенной выше таблице.

Вышеуказанный запрос работает отлично для меня Но занимает больше времени для выполнения за миллиарды записей.

+0

в соответствии с вашими условиями, '111 'также должны быть возвращены? –

+0

Есть ли какой-нибудь индекс в вашей таблице? –

+0

Просим опубликовать сценарий создания индекса. –

ответ

2

Попробуйте этот запрос:

SELECT colnum, coldate,colid 
FROM 
( 
select *,COUNT(1) OVER (PARTITION BY colnum) as cnt 
from (SELECT DISTINCT colnum, coldate,colid from testing) t 
) q 
where q.cnt=1 and q.coldate in ('2015-01-01') and q.colid = 1 

скрипку ссылка: http://sqlfiddle.com/#!6/650c0/4

+0

Это не будет соответствовать ожидаемому результату, так как '111', '2015-01-01', 1 будет на выходе – Bulat

+0

, не думайте, что это исправит. – Bulat

+1

Да, это имеет смысл, и это самый быстрый способ узнать. – Bulat

0

Попробуйте следующее. Вы также получите запись 111.

выберите * от тестирования

где coldate = '2015-01-01'

и colid = 1;

, а для времени выполнения вы просто создаете индекс на этой таблице. Это увеличит производительность выполнения.

Спасибо.

1

Я сделал некоторые предположения на основе результата в вашем примере.

  • вы хотите конкретную дату, а не другой даты
  • вы хотите, чтобы все colid (ы) (как в вашем примере)

Можете ли вы проверить, является ли это ожидаемый результат?

SELECT t.* 
FROM testing t 
     LEFT JOIN (SELECT * 
        FROM testing 
        WHERE coldate <> '2015-01-01') x 
       ON x.colnum = t.colnum 
WHERE x.colnum IS NULL 
0

Это будет интересно сравнить скорость на это:

SELECT colnum,colid, min(coldate) as coldate 
FROM testing 
GROUP BY colnum,colid 
HAVING COUNT(DISTINCT coldate) = 1 
    AND colid = 1 
    AND min(coldate) = '2015-01-01' 
+0

Просто вставьте эту «вставку в тестовые значения» ('333', '2015-01-01', 1); 'в 3 раза и запустите свой скрипт. Он должен показать результат, потому что он только в одну и ту же дату, но несколько раз, но он должен быть указан в результате – MAK

+0

Можете ли вы обновить свой вопрос с помощью этого примера PLS. – Bulat

+0

Я обновил запрос, чтобы подсчитать отличное количество дат – Bulat

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