Используя график рассеяния, вы можете получить доступ к параметру style
(или даже size
). Но вы можете не закончить с вашим предполагаемым макетом в конце. документация по точечной диаграмме .
Или вы можете использовать catplot
и играть со строками и столбцами. Seaborn Doc для Catplot
К сожалению, Seaborn не обеспечивает изначально то, что вы ищете: еще один уровень вложенности, кроме параметра hue
в stripplot
(см. документация Stripplot [ 117]. Открыты некоторые билеты на морское побережье, которые могут быть связаны, например, этот билет . Но я пришел по некоторым подобным запросам функций в морском вокзале, которые были отклонены, см. этот билет
]
Последняя возможность - погрузиться в примитивы matplotlib, чтобы манипулировать вашей диаграммой морского происхождения (так как морская волна находится только на вершине matplotlib). Само собой разумеется, что это потребует больших усилий и может привести к аннулированию морского происхождения первое место;)
Я не использовал бы явный курсор, чтобы сделать это. Steve F. больше не советует людям использовать явные курсоры, когда неявный курсор мог использоваться.
метод с count(*)
небезопасен. Если другая сессия удаляет строку, которая удовлетворила условию после того, как строка с эти count(*)
, и перед строкой с эти select ... into
, код выдаст исключение, которое не будет обработано.
вторая версия из исходного сообщения не имеет этой проблемы, и это обычно предпочитается.
Однако существует незначительное служебное использование исключения, и если Вы на 100% уверены, что данные не изменятся, можно использовать эти count(*)
, но я рекомендую против него.
я выполнил эти сравнительные тесты на [1 112] Oracle 10.2.0.1 на [1 113] Windows на 32 бита. Я только смотрю на прошедшее время. Существуют другие тестовые обвязки, которые могут предоставить больше подробную информацию (такую как количества фиксатора и используемая память).
SQL>create table t (NEEDED_FIELD number, COND number);
Таблица составлена.
SQL>insert into t (NEEDED_FIELD, cond) values (1, 0);
1 строка создается.
declare
otherVar number;
cnt number;
begin
for i in 1 .. 50000 loop
select count(*) into cnt from t where cond = 1;
if (cnt = 1) then
select NEEDED_FIELD INTO otherVar from t where cond = 1;
else
otherVar := 0;
end if;
end loop;
end;
/
процедура пуазейли / процедура SQL, успешно завершенная.
Истекший: 0:00:02.70
declare
otherVar number;
begin
for i in 1 .. 50000 loop
begin
select NEEDED_FIELD INTO otherVar from t where cond = 1;
exception
when no_data_found then
otherVar := 0;
end;
end loop;
end;
/
процедура пуазейли / процедура SQL, успешно завершенная.
Истекший: 0:00:03.06
Так как ВЫБОР В предполагает, что единственная строка будет возвращена, можно использовать оператор формы:
SELECT MAX(column)
INTO var
FROM table
WHERE conditions;
IF var IS NOT NULL
THEN ...
ВЫБОР даст Вам значение, если Вы будете доступны, и значение ПУСТОГО УКАЗАТЕЛЯ вместо исключения NO_DATA_FOUND. Издержки, представленные МАКСОМ (), будут минимальны к нулю, так как набор результатов содержит единственную строку. Это также имеет преимущество того, чтобы быть компактным относительно основанного на курсоре решения и не быть уязвимым для проблем параллелизма как двухступенчатое решение в исходном сообщении.
Альтернатива коду @Steve.
DECLARE
CURSOR foo_cur IS
SELECT NEEDED_FIELD WHERE condition ;
BEGIN
FOR foo_rec IN foo_cur LOOP
...
END LOOP;
EXCEPTION
WHEN OTHERS THEN
RAISE;
END ;
цикл не выполняется, при отсутствии данных. Курсор ДЛЯ циклов является способом пойти - они помогают избежать большого обслуживания. Еще более компактное решение:
DECLARE
BEGIN
FOR foo_rec IN (SELECT NEEDED_FIELD WHERE condition) LOOP
...
END LOOP;
EXCEPTION
WHEN OTHERS THEN
RAISE;
END ;
, Который работает, если Вы знаете полный избранный оператор во время компиляции.
@DCookie
я просто хочу указать, что можно бросить строки, которые говорят
EXCEPTION
WHEN OTHERS THEN
RAISE;
, Вы получите тот же эффект, если Вы бросите блок исключения все вместе, и номер строки, о котором сообщают для исключения, будет строкой, где исключение на самом деле выдается, не строка в блоке исключения, где это было повторно повышено.
Stephen Darlington делает очень правильное замечание, и Вы видите что при изменении моего сравнительного теста для использования более реалистично размерной таблицы, если я заполняю таблицу к 10 000 строк с помощью следующего:
begin
for i in 2 .. 10000 loop
insert into t (NEEDED_FIELD, cond) values (i, 10);
end loop;
end;
Тогда повторно выполняет сравнительные тесты. (Я должен был уменьшить количества цикла до 5 000 для получения соответствующего времени).
declare
otherVar number;
cnt number;
begin
for i in 1 .. 5000 loop
select count(*) into cnt from t where cond = 0;
if (cnt = 1) then
select NEEDED_FIELD INTO otherVar from t where cond = 0;
else
otherVar := 0;
end if;
end loop;
end;
/
PL/SQL procedure successfully completed.
Elapsed: 00:00:04.34
declare
otherVar number;
begin
for i in 1 .. 5000 loop
begin
select NEEDED_FIELD INTO otherVar from t where cond = 0;
exception
when no_data_found then
otherVar := 0;
end;
end loop;
end;
/
PL/SQL procedure successfully completed.
Elapsed: 00:00:02.10
метод за исключением теперь более двух раз как быстро. Так, почти для всех случаев, метода:
SELECT NEEDED_FIELD INTO var WHERE condition;
EXCEPTION
WHEN NO_DATA_FOUND....
способ пойти. Это даст корректные результаты и является обычно самым быстрым.
Если важно, чтобы Вы действительно сравнили обеих опций!
Однако я всегда использовал метод исключения, обоснование, являющееся, лучше только поразить базу данных однажды.
Да, Вы избегаете использовать курсоры
DECLARE
CURSOR foo_cur IS
SELECT NEEDED_FIELD WHERE condition ;
BEGIN
OPEN foo_cur;
FETCH foo_cur INTO foo_rec;
IF foo_cur%FOUND THEN
...
END IF;
CLOSE foo_cur;
EXCEPTION
WHEN OTHERS THEN
CLOSE foo_cur;
RAISE;
END ;
по общему признанию, это - больше кода, но он не использует ИСКЛЮЧЕНИЯ в качестве управления потоком, которому, изучив большинство моих МН / SQL из МН книги Программирования Steve Feuerstein / книги Программирования SQL, я верю, чтобы быть хорошей вещью.
, Быстрее ли это или не, я не знаю (я делаю очень мало МН / SQL в наше время).
Вместо того, что вложил курсор циклично выполняется, более эффективный подход должен был бы использовать один цикл курсора с внешним объединением между таблицами.
BEGIN
FOR rec IN (SELECT a.needed_field,b.other_field
FROM table1 a
LEFT OUTER JOIN table2 b
ON a.needed_field = b.condition_field
WHERE a.column = ???)
LOOP
IF rec.other_field IS NOT NULL THEN
-- whatever processing needs to be done to other_field
END IF;
END LOOP;
END;
Вы не должны использовать открытый, когда Вы используете для циклов.
declare
cursor cur_name is select * from emp;
begin
for cur_rec in cur_name Loop
dbms_output.put_line(cur_rec.ename);
end loop;
End ;
или
declare
cursor cur_name is select * from emp;
cur_rec emp%rowtype;
begin
Open cur_name;
Loop
Fetch cur_name into Cur_rec;
Exit when cur_name%notfound;
dbms_output.put_line(cur_rec.ename);
end loop;
Close cur_name;
End ;
Может бить мертвую лошадь здесь, но я сравнил курсора для цикла, и это работало о, а также no_data_found метод:
declare
otherVar number;
begin
for i in 1 .. 5000 loop
begin
for foo_rec in (select NEEDED_FIELD from t where cond = 0) loop
otherVar := foo_rec.NEEDED_FIELD;
end loop;
otherVar := 0;
end;
end loop;
end;
процедура пуазейли / процедура SQL, успешно завершенная.
Истекший: 0:00:02.18