Запросы на общее знание SQL

Реализовать запросы на стандартном SQL.
Нельзя использовать конструкции типа:
SELECT * FROM (SELECT * FROM) | SELECT TOP N | ROW_NUMBER() OVER () | Временные таблицы | Вендорные расширения и т.д.

  1. Есть таблица, содержащая поле «ID». Нужно выдать все встречающиеся более одного значения поля «ID».
    SELECT t.id FROM t GROUP BY t.id HAVING COUNT(t.id) > 1;

    Скрипт для проверки:

    CREATE TABLE "T" 
    ("ID" NUMBER
    ) TABLESPACE MIRAVILD_DATA;
    
    INSERT INTO t (t.id) VALUES (1);
    INSERT INTO t (t.id) VALUES (11);
    INSERT INTO t (t.id) VALUES (-1);
    INSERT INTO t (t.id) VALUES (-1);
    INSERT INTO t (t.id) VALUES (-1);
    INSERT INTO t (t.id) VALUES (1);
    INSERT INTO t (t.id) VALUES (2);
    INSERT INTO t (t.id) VALUES (2);
    INSERT INTO t (t.id) VALUES (3);
    INSERT INTO t (t.id) VALUES (1);
    
    COMMIT WORK;
    /
  2. Есть таблица, содержащая одно поле «ID» (типа INTEGER). Значение «ID» уникальны, всегда неотрицательны, но могут идти не подряд (некоторые значения пропущены). Написать запрос, который возвращает первое пропущенное значения поля «ID». Например, последовательность: 1, 2, 3, 5, 8, 13, 21, 34, 55. Необходимо вернуть значение 4 (первое пропущенное). Варианты запросов:
    SELECT min(x1.id + 1) as first_value
      FROM x x1
      LEFT JOIN x x2
        ON x2.id = x1.id + 1
     WHERE x2.id IS NULL;
    /
    SELECT min(x1.id + 1) as first_value
      FROM x x1
     WHERE NOT EXISTS (SELECT 1 FROM x x2 WHERE x2.id = x1.id + 1);
    /

    Скрипт для проверки:

    CREATE TABLE "X" 
    ("ID" INTEGER
    ) TABLESPACE MIRAVILD_DATA;
    
    CREATE UNIQUE INDEX "X_U_IDX" ON "X" ("ID") TABLESPACE MIRAVILD_INDEX;
    
    INSERT INTO x (x.id) VALUES (1);
    INSERT INTO x (x.id) VALUES (2);
    INSERT INTO x (x.id) VALUES (3);
    INSERT INTO x (x.id) VALUES (5);
    INSERT INTO x (x.id) VALUES (8);
    INSERT INTO x (x.id) VALUES (13);
    INSERT INTO x (x.id) VALUES (21);
    INSERT INTO x (x.id) VALUES (34);
    INSERT INTO x (x.id) VALUES (55);
    INSERT INTO x (x.id) VALUES (89);
    
    COMMIT WORK;
    /
  3. Есть таблица, содержащая поле «VAL». Указать количество уникальных значений в этом поле, отличных от NULL.
    SELECT COUNT(DISTINCT v.val) AS cnt FROM v;
    /

    Скрипт для проверки:

    CREATE TABLE "V" 
    ("VAL" NUMBER
    ) TABLESPACE MIRAVILD_DATA;
    
    INSERT INTO v (v.val) VALUES (1);
    INSERT INTO v (v.val) VALUES (11);
    INSERT INTO v (v.val) VALUES (-1);
    INSERT INTO v (v.val) VALUES (-1);
    INSERT INTO v (v.val) VALUES (-1);
    INSERT INTO v (v.val) VALUES (null);
    INSERT INTO v (v.val) VALUES (null);
    INSERT INTO v (v.val) VALUES (null);
    INSERT INTO v (v.val) VALUES (3);
    INSERT INTO v (v.val) VALUES (1);
    
    COMMIT WORK;
    /
  4. Есть таблица с уникальным полем «ID». Вывести первые 10 строк по возрастанию поля «ID». Только синтаксис стандартного SQL. Запасной вариант:
    SELECT y.id FROM y WHERE rownum <= 10 ORDER BY y.id ASC ;
    /

    Скрипт для проверки:

    CREATE TABLE "Y" 
    ("ID" NUMBER
    ) TABLESPACE MIRAVILD_DATA;
     
    CREATE UNIQUE INDEX "Y_U_IDX" ON "Y" ("ID") TABLESPACE MIRAVILD_INDEX;
    
    INSERT INTO y (y.id) VALUES (1);
    INSERT INTO y (y.id) VALUES (14);
    INSERT INTO y (y.id) VALUES (15);
    INSERT INTO y (y.id) VALUES (7);
    INSERT INTO y (y.id) VALUES (10);
    INSERT INTO y (y.id) VALUES (20);
    INSERT INTO y (y.id) VALUES (99);
    INSERT INTO y (y.id) VALUES (44);
    INSERT INTO y (y.id) VALUES (3);
    INSERT INTO y (y.id) VALUES (29);
    INSERT INTO y (y.id) VALUES (21);
    INSERT INTO y (y.id) VALUES (77);
    
    COMMIT WORK;
    /
  5. Есть запрос с GROUP BY. Что можно указать в списке выборки?. Фраза GROUP BY — сгруппировать строки по указанному общему признаку и выдать сведения, общие для каждой группы. В списке выборки (SELECT), можно указать одну или несколько стандартных агрегатных (обобщающих) функций: COUNT, MIN, MAX, SUM, AVG и т.д.
  6. Будут ли идентичны следующие выборки и почему:
    SELECT t1.a, MAX(t2.b)
      FROM table_1 t1, table_2 t2
     WHERE t1.a = t2.a
     GROUP BY t1.a;
    /
    
    SELECT t1.a, (SELECT MAX(t2.b) FROM table_2 t2 WHERE t2.a = t1.a)
      FROM table_1 t1
     GROUP BY t1.a;
    /

    Нет. Результарующий набор будет разным. В первом запросе будут отсутствовать пустые значения (NOT NULL). Во втором запросе будут присутствовать пустые значения (NULL).

P.S.
Конфигурация СУБД — Oracle Database 11g Express Edition Release 11.2.0.2.0
IDE — PL/SQL Developer Version 11.0.6.1776

Tags: , ,

Leave a Reply

You must be logged in to post a comment.