Сравнить два набора результатов SQL-запросов

1

Поэтому у меня есть приложение, которое проверяет запросы SQL SELECT на определенный ответ.

Сейчас он сравнивает результирующие наборы двух запросов с помощью некоторых циклов FOR из PHP. Он ищет каждый столбец из определенного запроса и пытается найти его во входном запросе;

Есть ли способ проверить это на уровне оракула?

Пример: скажем, у нас есть следующая таблица

 EMPNO ENAME      JOB              MGR HIREDATE         SAL       COMM     DEPTNO

  7369 SMITH      CLERK           7902 17-DEC-80        800                    20
  7499            SALESMAN        7698 20-FEB-81       1600        300         30
  7521 WARD       SALESMAN        7698 22-FEB-81       1250        500         30
  7566 JONES      MANAGER         7839 02-APR-81       2975                    20
  7654 MARTIN     SALESMAN        7698 28-SEP-81       1250       1400         30
  7698 BLAKE      MANAGER         7839 01-MAY-81       2850                    30
  7782 CLARK      MANAGER         7839 09-JUN-81       2450                    10
  7788 SCOTT      ANALYST         7566 13-JUL-87       3000                    20
  7839 KING       PRESIDENT            17-NOV-81       5000                    10
  7844 TURNER     SALESMAN        7698 08-SEP-81       1500          0         30
  7876 ADAMS      CLERK           7788 13-JUL-87       1100                    20
  7900 JAMES      CLERK           7698 03-DEC-81        950                    30
  7902 FORD       ANALYST         7566 03-DEC-81       3000                    20
  7934 MILLER     CLERK           7782 23-JAN-82       1300                    10

Определенный ответ:

 SELECT ENAME, JOB FROM EMP WHERE DEPTNO=20;

Входной ответ:

SELECT * FROM EMP WHERE DEPTNO=20;

Эти два запроса более руд менее эквивалентны по выбранным строкам.

Как я могу проверить этот факт?

  1. (Это 2 запроса equivalent- в терминах строк)
  2. (Входной запрос может содержать дополнительные столбцы)

Что я пробовал:

  1. используя операторы UNION/MINUS. (Проблема в том, что когда запросы имеют разное количество столбцов, MINUS не работает).

Какие-либо предложения?

Заранее спасибо.

  • 1
    больше руды менее эквивалентно с точки зрения выбранных рядов ? Нет, если они выполняются одновременно, они ТОЧНО эквивалентны с точки зрения выбранных строк. Если вы не вставите или не удалите промежуточный запрос. Это твой сценарий?
  • 0
    Если вы используете SQL Server, вы можете использовать sys.dm_exec_describe_first_result_set для получения метаданных о запросе и сравнения для ввода / ответа. Проверьте, есть ли что-то подобное в Oracle.
Показать ещё 1 комментарий
Теги:
plsql

1 ответ

1
Лучший ответ

В какой-то степени это зависит от того, какую информацию вы готовы полагаться на свое приложение для предоставления, и на что вы надеетесь извлечь динамически. Это также зависит от того, как вы должны задать вопрос Oracle.

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

WITH
  expected AS (
    -- select all the expected columns, plus a count
    SELECT ENAME, JOB, COUNT(*) AS count FROM (
      -- the standard query to test against
      SELECT ENAME, JOB FROM EMP WHERE DEPTNO=20
    ) reference
    -- group by all the columns of the result
    GROUP BY ENAME, JOB
  ),
  observed AS (
    -- choose only the expected columns (Oracle will barf if any are not present),
    -- plus a count
    SELECT ENAME, JOB, COUNT(*) AS count FROM (
      -- the query whose results are to be tested
      SELECT * FROM EMP WHERE DEPTNO=20
    ) user_specified
    -- group by all the columns of the reference result
    GROUP BY ENAME, JOB
  )
SELECT COUNT(*) as differences
FROM (
    (
      SELECT * FROM expected
      MINUS
      SELECT * FROM observed
    )
    UNION ALL
    (
      SELECT * FROM observed
      MINUS
      SELECT * FROM expected
    )
  ) differing_rows

Это в значительной степени шаблонный. Вы включаете весь ссылочный запрос в одном месте, весь запрос ввода в другом и (тот же) ожидаемый список столбцов в четырех отдельных местах. Результат запроса - это одна строка с одним столбцом, содержащим значение 0, если результаты запроса точно совпадают для интересующих столбцов (игнорируя порядок столбцов и строк) или значение больше нуля в противном случае. В случае, если запрос компонента возвращает повторяющиеся строки, общий результат проверяет, возвращают ли оба числа одинаковое количество копий каждой повторяющейся строки.

  • 0
    Спасибо за ответ, я понял: выберите только те столбцы, которые меня интересуют, а затем получите различия. Но что, если запрос ввода выглядит следующим образом: SELECT ENAME name, JOB FROM emp WHERE DEPTNO=20 ; Если на входе есть псевдонимы? Как я могу обобщить?
  • 0
    Столбцы в основном идентифицируются по их именам / псевдонимам. Если входной запрос назначает неожиданные псевдонимы столбцам, возможно, это неправильно . Тем не менее, возможно, нет необходимости проверять соответствие на основе порядка столбцов, но если это так, то я думаю, что вам нужно написать хранимую процедуру или пользовательскую функцию для доступа к ней. Боюсь, у меня нет конкретной реализации.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню