SQL 'in' clause
Aug. 9th, 2014 08:06 pm![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
Скажите мне такую вещь: список значений в in выражении в SQL можно вообще передать параметром, хоть в какой-нибудь СУБД?
В Firebird нельзя, ну я как-то не интересовался, как оно в других СУБД, использовал временную табличку и подзапрос с where exists (select 1 from TmpTbl ...) но что-то вот сегодня пришло в голову - а почему собственно нельзя?
В Firebird нельзя, ну я как-то не интересовался, как оно в других СУБД, использовал временную табличку и подзапрос с where exists (select 1 from TmpTbl ...) но что-то вот сегодня пришло в голову - а почему собственно нельзя?
no subject
Date: 2014-08-09 05:11 pm (UTC)no subject
Date: 2014-08-09 05:16 pm (UTC)Ни у кого нет, хотя фича самоочевидная.
no subject
Date: 2014-08-09 05:41 pm (UTC)select * from user_table1 where id in (select * from table(:my_collection))
table(:my_collection) -- это оператор, который коллекцию приводит к таблице
no subject
Date: 2014-08-09 06:07 pm (UTC)no subject
Date: 2014-08-09 07:44 pm (UTC)no subject
Date: 2014-08-09 07:58 pm (UTC)no subject
Date: 2014-08-09 09:26 pm (UTC)в примере таки sql, но использующий коллецию pl/sql
no subject
Date: 2014-08-09 05:44 pm (UTC)no subject
Date: 2014-08-09 06:06 pm (UTC)no subject
Date: 2014-08-09 06:14 pm (UTC)no subject
Date: 2014-08-09 06:17 pm (UTC)no subject
Date: 2014-08-09 06:19 pm (UTC)no subject
Date: 2014-08-09 06:32 pm (UTC)раскрывается как
c1 = a1 or c1 = a2 or ...
Можно сделать так
c1 = ANY(array)
что в принципе равносильно предыдущей записи с отличием, что в ANY можно передавать списки, массивы.
no subject
Date: 2014-08-09 07:25 pm (UTC)Это как-то очень уж неэффективно. Вроде нигде оно так не раскрывается.
no subject
Date: 2014-08-09 07:46 pm (UTC)no subject
Date: 2014-08-09 09:25 pm (UTC)IN (a1, a2, ...)
no subject
Date: 2014-08-09 09:58 pm (UTC)no subject
Date: 2014-08-10 11:06 am (UTC)no subject
Date: 2014-08-10 11:09 am (UTC)no subject
Date: 2014-08-10 12:42 pm (UTC)В T-SQL чуть ли не в MSDN пишут об эквивалентности запросов.
В PostgreSQL - точно не помню, но в плане выполнения тоже хэши видел, однако думаю, что конструкции эквивалентны.
А когда `IN (SQL statement)` встречается, то тут тот же принцип с той разницей, что в памяти надо хранить результат его выполнения. И PostgreSQL, и Oracle могут оказаться чувствительны к нему, если он достаточно велик, а в памяти они ограничены.
no subject
Date: 2014-08-10 04:15 pm (UTC)no subject
Date: 2014-08-09 06:51 pm (UTC)противогаз покусал?
no subject
Date: 2014-08-09 07:01 pm (UTC)no subject
Date: 2014-08-09 07:29 pm (UTC)Вы просто так хуйню пишете от жары али заказал такое кто?
no subject
Date: 2014-08-10 09:33 am (UTC)Теперь знаю хоть одну точную, достоверную деталь — противогаз не кусается.
no subject
Date: 2014-08-10 10:22 am (UTC)no subject
Date: 2014-08-10 03:09 pm (UTC)no subject
Date: 2014-08-10 03:30 pm (UTC)no subject
Date: 2014-08-10 04:14 pm (UTC)no subject
Date: 2014-08-10 02:07 pm (UTC)Интеллигентные люди используют эвфемизм who knew.
no subject
Date: 2014-08-10 04:21 pm (UTC)На него нашло что-то русское.
no subject
Date: 2014-08-10 04:32 pm (UTC)no subject
Date: 2014-08-10 04:50 pm (UTC)no subject
Date: 2014-08-09 07:03 pm (UTC)$stmt->execute(array("male", "female", "transgender", "developer"));
Увы, да(
no subject
Date: 2014-08-09 07:23 pm (UTC)Запрос: select * from data.street where id_street in (select unnest(?)) где ? является параметром
Сам код:
PreparedStatement selectPs = connection.prepareStatement("select * from data.street where id_street in (select unnest(?))");
Integer[] a = new Integer[]{927,929,930,931,932,933,934,935,936,937};
Array a2 = connection.createArrayOf("int",a);
selectPs.setArray(1,a2);
Используется именно Integer, а не int, потому что требуется ссылочный тип. Значение параметра устанавливается по индексу, потому что это голый JDBC.
Функция unnest разворачивает массив в набор строк (http://www.postgresql.org/docs/9.3/static/functions-array.html)
no subject
Date: 2014-08-09 07:37 pm (UTC)no subject
Date: 2014-08-09 08:07 pm (UTC)Кажется, ещё на ib.demo.ru я возмущался, что нелья делать группировку как и ордер бай - по номерам полей, и они это сделали.
no subject
Date: 2014-08-09 08:43 pm (UTC)no subject
Date: 2014-08-09 08:45 pm (UTC)CREATE TYPE [dbo].[IdsTableType] AS TABLE (
[Id] INT NULL);
В дот.нете все работает через SqlMetaData и SqlDataRecord, в общем в итоге можно in засунуть в переменную собственного типа.
Только один забавный глюк - т.к. sql сервер строит планы запросов по имени переменных, то внезапно когда в in 2 значения и 10.000 значений - планы одинаковые.
Бороли это буквально таким кодом
var parameterName = name + GetRangePostfix(records.Count);
который по логарифму делает параметру разные имена :)
no subject
Date: 2014-08-09 10:50 pm (UTC)В качеестве параметра передавать array
no subject
Date: 2014-08-10 07:19 am (UTC)no subject
Date: 2014-08-10 04:13 pm (UTC)ты зря отмалчиваешься.
no subject
Date: 2014-08-10 09:28 pm (UTC)В MSSQL у решения есть очевидный недостаток: отсутствие статистики, т.е. в зависимости от объёма данных для "IN" может потребоваться подсказка "INNER MERGE JOIN". По умолчанию явно будет LOOP JOIN.
no subject
Date: 2014-08-11 09:36 am (UTC)