Получение записи с единственным документом по приоритетному вопросу - PullRequest
1 голос
/ 15 июля 2011

У меня есть две таблицы:

контакты:

id, name
1   Alex
2   John

документы:

id, contactID, type
1     1         1
2     1         2
...
30    1         3
31    2         1
32    2         3

Я хочу получить имя контакта и тип документа. единственная запись для каждого контакта . Контакт может иметь несколько типов документов (единственный документ для каждого типа), и у меня есть следующий приоритет для типов документов: 2, 3, 1. Например, у Алекса есть документы всех типов, но я должен получить только:

Alex, 2

У Джона есть типы документов = 1, 3, в результате я должен получить:

John, 3

База данных Oracle. Но если вы сможете дать стандартное решение sql, было бы здорово

Ответы [ 2 ]

3 голосов
/ 15 июля 2011

Oracle 9i +, используйте:

WITH example AS (
  SELECT c.name,
         d.type,
         ROW_NUMBER() OVER (PARTITION BY c.id
                                ORDER BY CASE d.type
                                           WHEN 2 THEN 1
                                           WHEN 3 THEN 2
                                           WHEN 1 THEN 3
                                           ELSE 4
                                         END) AS rnk    
    FROM CONTACTS c
    JOIN DOCUMENTS d ON d.contactid = c.id)
SELECT e.name, e.type
  FROM example e
 WHERE e.rnk = 1

... или версия без фактора подзапроса (AKA CTE) (по-прежнему 9i +):

SELECT e.name, e.type
  FROM (SELECT c.name,
               d.type,
               ROW_NUMBER() OVER (PARTITION BY c.id
                                      ORDER BY CASE d.type
                                                 WHEN 2 THEN 1
                                                 WHEN 3 THEN 2
                                                 WHEN 1 THEN 3
                                                 ELSE 4
                                               END) AS rnk    
          FROM CONTACTS c
          JOIN DOCUMENTS d ON d.contactid = c.id) e
 WHERE e.rnk = 1
2 голосов
/ 15 июля 2011

Используйте встроенное представление, в котором типы сопоставляются с приоритетами, затем группируются по контактам, затем сопоставляются приоритеты с типами.

SELECT C.name
       DECODE( V.priority, 'A', 2, 'B', 3, 'C', 1 ) AS type
FROM   contacts C
    ,  (    SELECT   D.contactid
                ,    MIN( DECODE( D.type, 2, 'A', 3, 'B', 1, 'C' ) ) AS priority
            FROM     documents D
            GROUP BY D.contact_id
       ) V
WHERE  V.contactid = C.id
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...