Запрос SQL Not IN требует времени с аналогичной таблицей

У меня есть 2 таблицы, предположим, что table_1 и table_2 table_1 имеет 56 столбцов и 1,2 миллиона записей, мой запрос похож на

table_1 нравится

RollNumber | Subject | G         | Part | Status  
------------------------------------------------  
1          | 1       | 1         | 1    |  1  
1          | 1       | 1         | 2    |  1  
1          | 2       | 1         | 1    |  1  
1          | 2       | 1         | 2    |  5  
1          | 3       | 1         | 1    |  0  
1          | 3       | 1         | 2    |  1  
2          | 1       | 2         | 1    |  1  
2          | 1       | 2         | 2    |  1  
2          | 2       | 2         | 1    |  1  
2          | 2       | 2         | 2    |  1  
2          | 3       | 2         | 1    |  1  
2          | 3       | 2         | 2    |  1 
3          | 1       | 2         | 1    |  1  
3          | 1       | 2         | 2    |  1  
3          | 2       | 2         | 1    |  1  
3          | 2       | 2         | 2    |  1  
3          | 3       | 2         | 1    |  0  
3          | 3       | 2         | 2    |  1  

Я хочу, чтобы все RollNumber (группа со вторым и третьим столбцами) из таблицы_1, где любой статус равен 0, но не хочу, чтобы студенты, у которых также есть статус = 5 (или отличный от 1)

я пробовал это

select * from table_1 as t1  
inner join table_2 as t2  
on  t1.column2 = t2.column2 and t1.column3 = t2.column3 and t1.column4 = t2.column4  
where t1.column1 not in  
     (select column1 from table_1 where status = 5)

Это самый внутренний запрос моего запроса qhole
я также пробовал предложение EXCEPT
Оба запроса выполняются слишком долго


person Brainiac    schedule 23.02.2017    source источник
comment
зачем использовать подзапрос для фильтрации status?   -  person Jacky Montevirgen    schedule 23.02.2017
comment
Покажите план выполнения запроса. Вы добавили индексы к column1, column2, column3 и status?   -  person kennytm    schedule 23.02.2017
comment
@kennytm Я отредактировал вопрос, пожалуйста, просмотрите его сейчас ,,, спасибо   -  person Brainiac    schedule 23.02.2017


Ответы (3)


Начиная с SQL Server 2008 вы можете использовать count() over() для подсчета общего количества строк в данной группе, имеющих определенное значение.

В этом случае вам нужно подсчитать количество status <> 1 на группу и выбрать только строки, принадлежащие группе с количеством 0.

select * from (
    select * , 
      count(case when status <> 1 then 1 end) over(partition by RollNumber, G) c
    from table_1
) t where c = 0
person FuzzyTree    schedule 23.02.2017
comment
это работает ,,, но проблема в том, что мне нужно преобразовать в LINQ на С #, кстати, спасибо - person Brainiac; 23.02.2017
comment
Если вам нужна помощь в преобразовании запроса в LINQ, предлагаю открыть новый вопрос :) - person FuzzyTree; 23.02.2017
comment
я хочу, чтобы этот запрос также для mysql - person Brainiac; 06.03.2017

Вы можете использовать EXISTS вместо NOT IN.. Это будет быстрее, так как будет boolean сравнение вместо string.

select * from table_1 as t1  
inner join table_2 as t2  
on t1.column1 = t2.column1 and t1.column2 = t2.column2 and t1.column3 = t2.column3  
where not EXISTS  
     (select 1 from table_1 where status = 5 and t1.column3 = table_1.column3)
person Mit Bhatt    schedule 23.02.2017

Попробуйте использовать NOT EXISTS вместо NOT IN

SELECT * 
FROM table_1 AS t1  
INNER JOIN table_2 AS t2  
ON t1.column1 = t2.column1 AND t1.column2 = t2.column2 AND t1.column3 = t2.column3  
WHERE NOT EXISTS(
                    SELECT 1
                    FROM table_1
                    WHERE status=5 AND column3=t1.column3
                                                           )
person Jibin Balachandran    schedule 23.02.2017