|
Программирование >> Преобразование значений null
count(*) as cnt from emp group by empno,ename,job,mgr,hiredate,sal,comm,deptno EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO CNT 7521 WARD SALESMAN 7698 22-FEB-1981 1250 500 30 2 Результирующее множество включает строку представления V, которой или нет в таблице EMP, или ее кардинальное число отличается от кардинального числа строки таблицы EMP. В данном случае обнаруживается и возвращается строка-дубликат для служащего WARD. Если вам по-прежнему не до конца понятно, как формируется результирующее множество, выполните каждый из запросов до и после EXCEPT по отдельности. Вы увидите, что единственное отличие между двумя результирующими множествами - значение столбца CNT для служащего WARD из представления V. Часть запроса после UNION ALL выполняет операцию, являющуюся зеркальным отображением запроса, предшествующего UNION ALL. Этот запрос возвращает строки таблицы EMP, которых нет в представлении V: select empno,ename,job,mgr,hiredate,sal,comm,deptno, count(*) as cnt from emp group by empno,ename,job,mgr,hiredate,sal,comm,deptno minus select empno,ename,job,mgr,hiredate,sal,comm,deptno, count(*) as cnt from v group by empno,ename,job,mgr,hiredate,sal,comm,deptno EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO CNT 7521 WARD SALESMAN 7698 22-FEB-1981 1250 500 30 1 7782 CLARK MANAGER 7839 09-JUN-1981 2450 10 1 7839 KING PRESIDENT 17-NOV-1981 5000 10 1 7934 MILLER CLERK 7782 23-JAN-1982 1300 10 1 Потом UNION ALL комбинирует результаты и формирует окончательное результирующее множество. MySQL и SQL Server Запросы перед и после операции UNION ALL очень похожи. Чтобы понять, как работает решение с использованием подзапроса, просто отдельно выполните запрос, предшествующий UNION ALL. Запрос ниже -это строки 1-27 кода раздела Решение : select * from ( select e.empno,e.ename,e.job,e.mgr,e.hiredate, e.sal,e.comm,e.deptno, count(*) as cnt from emp e group by empno,ename,job,mgr,hiredate, sal,comm,deptno where not exists ( select null from ( select v.empno,v.ename,v.job,v.mgr,v.hiredate, v.sal,v.comm,v.deptno, count(*) as cnt from v group by empno,ename,job,mgr,hiredate, sal,comm,deptno
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO CNT 7521 WARD SALESMAN 7698 22-FEB-1981 1250 500 30 1 7782 CLARK MANAGER 7839 09-JUN-1981 2450 10 1 7839 KING PRESIDENT 17-NOV-1981 5000 10 1 7934 MILLER CLERK 7782 23-JAN-1982 1300 10 1 Обратите внимание, что сравниваются не таблица EMP и представление V, а вложенное представление E и вложенное представление V. Для каждой строки определяется кардинальное число, которое возвращается как атрибут этой строки. Происходит сравнение всех строк и этих их атрибутов, показывающих количество таких строк в таблице. Если возникают сложности с пониманием, как происходит сравнение, выполните подзапросы отдельно. На следующем этапе нужно найти во вложенном представлении Е все строки (включая CNT), которых нет во вложенном представлении V. Для сравнения используются связанный подзапрос и операция NOT EXISTS. Объединения выявят все одинаковые строки, а в результат войдут те строки вложенного представления Е, которых нет среди строк, возвращенных объединением. Запрос, следующий после UNION ALL, делает противоположную операцию: он находит во вложенном представлении V строки, которых нет во вложенном представлении Е:
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO CNT 7521 WARD SALESMAN 7698 22-FEB-1981 1250 500 30 2 Затем UNION ALL комбинирует результаты и формирует окончательное результирующее множество. Алес Спектик (Ales Spectic) и Джонатан Генник (Jonothan Gennick) в своей книге Transact-SQL Cookbook (OReilly) приводят альтернативное решение. Смотрите раздел главы 2 Com-paring Two Sets for Equality*. Идентификация и устранение некорректного использования декартова произведения Задача Требуется возвратить имя каждого служащего 10-го отдела и местонахождение отдела. Следующий запрос не обеспечивает правильного формирования необходимого результирующего множества: select e.ename, d.loc from emp e, dept d select * from ( select v. empno, v.ename,v.job,v.mgr,v.hiredate, v.sal,v.comm,v.deptno, count(*) as cnt from v group by empno,ename,job,mgr,hiredate, sal,comm,deptno where not exists ( select null from ( select e.empno,e.ename,e.job,e.mgr,e.hiredate, e.sal,e.comm,e.deptno, count(*) as cnt from emp e group by empno,ename,job,mgr,hiredate, sal,comm,deptno
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки. |