获取优先级为

时间:2016-03-10 09:46:36

标签: sql oracle

我有以下表结构:

形式

RID | MODULE
------------
1   | indiv
2   | indiv
3   | indiv

翻译

RID | LANG | VALUE | MODULE | TAG |
-----------------------------------
1   |   en |car    |        |     |
1   |   en |truck  |indiv   |     |
1   |   en |boat   |indiv   |C100 |
2   |   en |hat    |        |     |
3   |   en |cat    |        |     |
3   |   en |dog    |indiv   |     |
4   |   en |light  |        |     |
5   |   en |dark   |        |     |

根据RID和{{1}的附加(但不是必需的)参数,我需要从translations表中每module只获取一行列,即:

没有输入参数的结果

tag

结果有一个输入参数 RID | LANG | VALUE | MODULE | TAG | ----------------------------------- 1 | en |car | | | 2 | en |hat | | | 3 | en |cat | | |

module='indiv'

如果我有两个输入参数,结果为:

结果有两个参数: RID | LANG | VALUE | MODULE | TAG | ----------------------------------- 1 | en |truck |indiv | | 2 | en |hat | | | 3 | en |dog |indiv | |

module='indiv' AND tag='c100'

如何仅在ORACLE数据库服务器上使用SQL实现此目的?对于具有两个参数的最后一个案例的查询示例对我来说已经足够了,因为之前的案例是来自最后一个案例的子集,我相信这些列的RID | LANG | VALUE | MODULE | TAG | ----------------------------------- 1 | en |boat |indiv |C100 | 2 | en |hat | | | 3 | en |dog |indiv | | 。如果您认为所有这些情况都太不同并且需要不同的SQL语句,那么您也可以编写它们。

谢谢!

2 个答案:

答案 0 :(得分:2)

SELECT *
FROM   (
  SELECT  t.*,
          ROW_NUMBER() OVER (
            PARTITION BY RID
            ORDER BY CASE
                     WHEN module = LOWER( :mod ) AND tag = UPPER( :tag ) THEN 1
                     WHEN                            tag = UPPER( :tag ) THEN 2
                     WHEN module = LOWER( :mod ) AND tag IS NULL         THEN 3
                     WHEN module IS NULL         AND tag IS NULL         THEN 4
                                                                         ELSE 5
                     END
        ) AS rn
  FROM  translations t
  WHERE ( module IS NULL OR module = LOWER( :mod ) )
  OR    ( tag IS NULL OR tag = UPPER( :tag ) )

)
WHERE  rn = 1;

答案 1 :(得分:0)

我认为应该这样做。

SELECT *
FROM (
  SELECT F.RID,
         T.LANG,
         T.VALUE,
         T.MODULE,
         T.TAG,
         RANK() OVER(PARTITION BY F.RID
                     ORDER BY DECODE(T.MODULE, :module, 1, 2),
                              DECODE(T.TAG,    :tag,    1, 2))   RANK
  FROM   forms F INNER JOIN translations T
    ON T.RID = F.RID)
WHERE RANK = 1

因此,您对MODULE = :module或/和TAG = :tag更高的行进行排名。你仍然需要与领带有关,但你明白了。 RANK离开了关系,ROW_NUMBER没有。

由于您的示例,我将MODULE高于TAG。如果您可以输入没有模块的标签,则可能需要更改它。

此外,DECODE将NULL映射为NULL,因此如果未设置:module,则将匹配MODULE中具有NULL的行。