SQL Challenge - отображение N (1, X или All) строк с определенным значением столбца - PullRequest
2 голосов
/ 06 сентября 2011

Вот утренний вызов: у вас есть таблица с такими строками:

=> select * from candidates;
 id |   name   
----+----------
  1 | JOhn Doe
  2 | Melinda
  3 | Bill
  4 | Jane
(4 rows)

=> select * from evaluation order by id;
 id | score |                reason                
----+-------+--------------------------------------
  1 | RED   | Clueless!
  1 | AMBER | Came in dirty jeans
  2 | GREEN | Competenet and experienced
  2 | AMBER | Was chewing a gum
  3 | AMBER | No experience in the industry sector
  3 | AMBER | Has knowledge gaps
(6 rows)

У Джона красный, у Мелинды зеленый и янтарный, у Билла только янтарный, а у Джейн еще не давали интервью.

Ваша миссия, если вы решите принять ее, это сгенерировать запрос, который отображает результаты для одобрения босса. Босс любит, чтобы результаты были представлены как:

  • Если у кандидата ЗЕЛЕНЫЙ, отобразите только зеленый и игнорируйте красные и янтарные цвета.
  • Если у кандидата есть красные и янтарные или только янтарные цвета, отобразите их все, но сначала появится красный счет, чтобы он мог пропустить янтарь, если КРАСНЫЙ действительно плох.
  • отображать СЕРЫЙ для всех кандидатов, которые еще не были опрошены («Джейн»)

Правила игры:

  • Нет функций! Должен быть один SQL-запрос (сколько угодно подзапросов)
  • Любой вариант SQL принят, но ANSI SQL 92 или более поздняя версия приносит вам больше очков
  • Старайтесь избегать встроенных переменных, если можете (@foo в MySQL)

Мой собственный ответ соответствовал групповому мышлению:

SELECT *
FROM   evaluation e1
       NATURAL JOIN candidates
WHERE  score = 'GREEN'
        OR ( score IN ( 'RED', 'AMBER' )
             AND NOT EXISTS (SELECT 1
                             FROM   evaluation e2
                             WHERE  e1.id = e2.id
                                    AND score = 'GREEN') )
UNION
SELECT id,
       'GREY'              AS score,
       'Not yet evaluated' AS reason,
       name
FROM   candidates
WHERE  id NOT IN (SELECT id
                  FROM   evaluation)
ORDER  BY 1,
          2 DESC  

Ответы [ 4 ]

4 голосов
/ 06 сентября 2011

Это переходный SQL-92:

SELECT c.name, e.*
  FROM candidates AS c
       JOIN (
             SELECT *
               FROM evaluation
              WHERE score = 'GREEN'
             UNION
             SELECT *
               FROM evaluation AS e1
              WHERE score IN ('AMBER', 'RED')
                    AND NOT EXISTS (
                                    SELECT * 
                                      FROM evaluation AS e2
                                     WHERE e2.id = e1.id
                                           AND e2.score = 'GREEN'
                                   )                                    
            ) AS e 
          ON c.id = e.id
UNION
SELECT c.name, c.id, 'GREY', '(not interviewed)'
  FROM candidates AS c
 WHERE NOT EXISTS (
                   SELECT *
                     FROM evaluation AS e 
                    WHERE e.id = c.id
                   )
ORDER BY id, score DESC;

Альтернативный (промежуточный SQL-92):

SELECT c.name, e.id, e.score, e.reason 
  FROM candidates AS c
       JOIN (
             SELECT *
               FROM evaluation
             EXCEPT
             SELECT *
               FROM evaluation
              WHERE score IN ('AMBER', 'RED')
                    AND id IN ( SELECT id FROM evaluation WHERE score = 'GREEN' )
            ) AS e 
          ON c.id = e.id
UNION
SELECT name, id, 'GREY' AS score, '(not interviewed)' AS reason
  FROM candidates
 WHERE id NOT IN ( SELECT id FROM evaluation )
ORDER BY id, score DESC;
3 голосов
/ 06 сентября 2011
SELECT
        c.id                       AS id
      , c.name                     AS name
      , COALESCE(e.score, 'GREY')  AS score
      , e.reason                   AS reason
FROM 
        candidates    c
    LEFT JOIN
        evaluation    e
            ON e.id = c.id
WHERE
        e.score = 'GREEN'
    OR
        NOT EXISTS
          ( SELECT *
            FROM evaluation    ee
            WHERE ee.id = c.id
              AND ee.score = 'GREEN'
          )
ORDER BY
        id      ASC
      , score   DESC 
0 голосов
/ 27 мая 2013
SELECT A.ID
    , A.NAME
    , B.SCORE
    , B.REASON
FROM CANDIDATES A
LEFT JOIN EVALUATION B
    ON A.ID = B.ID
WHERE B.SCORE = 'GREEN'
UNION
SELECT A.ID
    , A.NAME
    , COALESCE(B.SCORE,'GREY')
    , B.REASON
FROM CANDIDATES A
LEFT JOIN EVALUATION B
    ON A.ID = B.ID
WHERE A.ID NOT IN (SELECT ID FROM EVALUATION WHERE SCORE = 'GREEN')
ORDER BY ID, SCORE DESC;
0 голосов
/ 03 января 2012
           SELECT c.id,
               c.name,
               nvl(e.score, 'GREY'),
               nvl(e.reason, 'Not yet interviewed')
          FROM candidates c, evaluation e
         where c.id = e.id(+)
           and ((e.score = 'GREEN') or
               (e.score in ('RED', 'AMBER') and not exists
                (select null
                    from evaluation e2
                   where e2.id = e.id
                     and e2.score = 'GREEN')) or e.score is null)
         order by c.id, e.score desc;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...