我有以下表结构:
形式
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语句,那么您也可以编写它们。
谢谢!
答案 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的行。