当外部查询结果为空时,选择子查询的结果

时间:2018-12-26 05:06:35

标签: sql postgresql subquery

我正在使用postgres 9.4。我有两个表tblcomponenttblprofile,没有外键引用。

我想从两个表中选择数据。关系就像

tblcomponent-> tblprofile

如果在tblprofile中找不到所需的数据,则仅必须选择tblcomponent数据。如果tblcomponent本身不包含请求的数据,则无需获取数据。

查询:

SELECT subquery1.pk_szid, subquery1.xmldata, tblprofile.pk_szid, tblprofile.xmldata
FROM tblprofile,
 (SELECT tblcomponent.pk_szid, tblcomponent.xmldata 
  FROM tblcomponent WHERE pk_szid != 'DEFAULT' ) subquery1
WHERE  
CAST((xpath('/Profile/ComponentIDs/ComponentID[@Family="Flow"]/text()', tblprofile.xmldata))[1] AS TEXT) = subquery1.pk_szid

以上查询返回两个表中是否都存在数据。当外部查询(即where子句失败)时,如何从subquery1获取数据?

例如:

tblcomponent

| pk_szid | xmldata        |
+---------+----------------+
| a1      |  xmldata       |
| a2      |  xmldata       |
| a3      |  xmldata       |

tblprofile

| pk_szid | xmldata        |
+---------+----------------+
| b1      |  xmldata       | // contains a1
| b2      |  xmldata       | // does not contain any of tblcomponent.pk_szid

在这里,“ b1”记录的xmldata包含tblcomponent.pk_szid。当我输入'a1'时,上述查询的结果将是

| pk_szid      | xmldata     |   pk_szid    |  xmldata     |
+--------------+-------------+--------------+--------------+
| a1           | xmldata     |     b1       |   xmldata    |

当我输入“ a2”时,

  | pk_szid      | xmldata     |   pk_szid    |  xmldata     |
  +--------------+-------------+--------------+--------------+

我想要类似的东西

 | pk_szid      | xmldata     |   pk_szid    |  xmldata     |
 +--------------+-------------+--------------+--------------+
 | a2           | xmldata     |              |              |

如何从subquery1获取此内容?

1 个答案:

答案 0 :(得分:0)

尝试将外部查询和子查询重构为单独的CTE,然后将其左联接:

WITH cte1 AS (
    SELECT pk_szid, xmldata,
        CAST((xpath('/Profile/ComponentIDs/ComponentID[@Family="Flow"]/text()', xmldata))[1] AS TEXT) AS xml_content
    FROM tblprofile
),
cte2 AS (
    SELECT pk_szid, xmldata 
    FROM tblcomponent
    WHERE pk_szid != 'DEFAULT'
)

SELECT
    t2.pk_szid,
    t2.xmldata,
    t1.pk_szid,
    t1.xmldata
FROM cte1 t1
LEFT JOIN cte2 t2
    ON t1.xml_content = t2.pk_szid;

我们可以编写上面的一些变体,但是基本思想是在select子句中计算XPath值,然后使用该值进行左连接。左联接可防止删除记录。