“ WHERE x.xxx IN”中的多个外键列匹配条件

时间:2019-02-04 21:01:59

标签: sql oracle

这个问题很难回答。

有效地,我试图编写一个查询来从表“ ste_file”中获取文件信息,该信息与表“ st_chemical”上的所有条目相对应。化学表与文件表(idfile_primary)有一个直接匹配,化学表有两个不同的“文件集合”,它具有外键(clfilecoll_other和clfilecoll_MSDS),这些外键与文件集合表“ ste_filecoll”匹配,依次通过“ idfile”列引用“ ste_file”中的多个文件

我编写的大多数查询版本都无法使用-它们只会不断旋转。我终于结束了:

SELECT
    c.idchemical,
    f.idfile as "id",
    f.szname as "name"
from ste_file f, st_chemical c
WHERE f.idfile IN (
        SELECT fc.idfile
        FROM ste_filecoll fc
        WHERE fc.clfilecoll = c.clfilecoll_msds
    )
UNION
SELECT
    c.idchemical,
    f.idfile as "id",
    f.szname as "name"
from ste_file f, st_chemical c
WHERE f.idfile IN (
        SELECT fc.idfile
        FROM ste_filecoll fc
        WHERE fc.clfilecoll = c.clfilecoll_other
)
UNION
    SELECT
        c.idchemical,
        f.idfile as "id",
        f.szname as "name"
    from ste_file f, st_chemical c
    WHERE f.idfile = c.idfile_primary;

这行得通,但感觉太草率了-我可能正在做大量的表扫描。有没有更清洁的方法可以做到这一点?我尝试了许多变体,例如在WHERE IN子句中改用UNION的地方,或者尝试完全不合并,但是它们都从不返回任何内容,只是无休止地运行。无效的查询示例:

SELECT
    c.idchemical,
    f.idfile as "id",
    f.szname as "name"
from ste_file f, st_chemical c
WHERE f.idfile IN (
        SELECT fc.idfile
        FROM ste_filecoll fc
        WHERE fc.clfilecoll = c.clfilecoll_msds
    UNION
        SELECT fc.idfile
        FROM ste_filecoll fc
        WHERE fc.clfilecoll = c.clfilecoll_other
);

这只是无休止地运行。有什么建议或想法可以简化吗?我有很多与此查询类似的查询,而且我想我缺少一些基本概念可以更清楚地涵盖这一点。

2 个答案:

答案 0 :(得分:0)

好吧,如果不查看数据模型和数据样本,这会有些困难,但是呢?

SELECT
    c.idchemical,
    f.idfile id,
    f.szname name
from ste_file f, st_chemical c
WHERE exists (
        SELECT null
        FROM ste_filecoll fc
        WHERE (
            (fc.idfile = f.idfile) and
            (fc.clfilecoll = c.clfilecoll_msds or fc.clfilecoll = c.clfilecoll_other)
        ) 
    ) 
or f.idfile = c.idfile_primary

可能是故意的,但您也缺少ste_file f, st_chemical c

之间的联接

答案 1 :(得分:0)

如果您使用的是12c或更高版本,则可以尝试以下操作:

SELECT c.idchemical,
       f.idfile as "id",
       f.szname as "name"
FROM  ste_chemical c 
CROSS APPLY ( SELECT fc.idfile 
              FROM ste_filecoll fc 
              WHERE fc.clfilecol1 IN ( c.clfilecol1_msds, c.clfilecol1_other )
              UNION
              SELECT c.idfile_primary idfile FROM DUAL ) fc
INNER JOIN ste_file f ON f.idfile = fc.idfile;

当我遇到类似这样的异常加入条件时,有时我会发现CROSS APPLY很有帮助。