【问题标题】:Getting record with the only document by priority issue通过优先问题获取唯一文档的记录
【发布时间】:2011-07-15 10:24:37
【问题描述】:

我有两张桌子:

联系人:

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 拥有所有类型的文档,但我应该只得到:

Alex, 2

John 的文档类型 = 1、3,因此我应该得到:

John, 3

甲骨文数据库。但是如果你能给出sql标准的解决方案那就太好了

【问题讨论】:

  • 你有一个单独的表来规定优先级吗?
  • 这是一个相当有趣的问题。我想知道有多少答案会通过对函数(type*8+3)%10 进行排序来实现您的优先级要求。以一种变态的方式工作。 :-)
  • @Alex R.,不,我没有。
  • @Alexandr:那你如何确定优先级?还是总是 2、3、1?
  • @Alex R.,总是2、3、1。假设在查询中配置了

标签: sql oracle


【解决方案1】:

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】:

使用内联视图将类型映射到优先级,然后按联系人分组,然后将优先级映射回类型。

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

【讨论】:

  • 谢谢,你的例子有效。但是有没有替代的方法?例如,使用 Oracle 分析函数?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-01-22
  • 1970-01-01
  • 2015-04-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-06
相关资源
最近更新 更多