繁体   English   中英

SQL子查询与UNION ALL查询结合

[英]SQL subquery combine with UNION ALL query

我有两个表:具有ID和Cost列的商品,以及具有goodid,languageid,title列的good_texts。 所以good_texts包含翻译。

我有一个查询,如果可用,选择当前语言的标题,如果不可用,则选择默认标题:

    SELECT
    *
FROM
    good_texts
WHERE
    languageid = 2
UNION ALL
    SELECT
        *
    FROM
        good_texts
    WHERE
        languageid = 1 AND goodid = 92
    AND goodid NOT IN (
        SELECT
            goodid
        FROM
            good_texts
        WHERE
            languageid = 2 and goodid = 92
    )

这可以正常工作,并且只返回一行。 现在,我尝试编写查询以从良好表中获取所有数据以及从good_texts表中获得标题。 我正在尝试使用以下查询执行此操作:

    SELECT
    s1.id,
    s1.cost,
    (SELECT
    s2.title
FROM
    good_texts s2
WHERE
    languageid = 2
UNION ALL
    SELECT
        s3.title
    FROM
        good_texts s3
    WHERE
        languageid = 1 AND s3.goodid = s1.id
    AND s3.goodid NOT IN (
        SELECT
            s4.goodid
        FROM
            good_texts s4
        WHERE
            languageid = 2 AND s4.goodid = s1.id
    ))
FROM
    goods s1

但这不会出错

子查询返回的多于一行用作表达式

我不明白为什么我的子查询甚至返回多行,因此如果单独运行它会返回一行。 我的目标如何实现?

您想要的查询如下所示:

SELECT gt.*
FROM good_texts gt
WHERE gt.languageid = 2
UNION ALL
SELECT gt.*
FROM good_texts gt
WHERE gt.languageid = 1 AND
      NOT EXISTS (SELECT 1
                  FROM good_texts gt2
                  WHERE gt2.goodid = gt.goodid AND gt2.languageid = 2
                 );

第一个获取的语言ID为“ 2”的所有内容。 第二个将获取所有语言标识为“ 1”但不为“ 2”的商品。

在Postgres中,使用DISTINCT ON可以更轻松地完成此操作:

SELECT DISTINCT ON (gt.goodid) gt.*
FROM good_texts gt
WHERE gt.languageid IN (1, 2)
ORDER BY gt.goodid, (CASE WHEN gt.languageid = 2 THEN 1 ELSE 2 END);

条件不一样

在工作一个查询是

    AND goodid NOT IN (
    SELECT
        goodid
    FROM
        good_texts
    WHERE
        languageid = 2 and goodid = 92
)

而在不工作的是

AND title NOT IN (
    SELECT
        title
    FROM
        good_texts s4
    WHERE
        languageid = 2 AND s4.goodid = s1.id
)

您在子句中的子查询中的..中选择了不同的列goodidtitle

select语句期望对一行数据进行操作。 from和where子句将确定查询返回的数据行数(其他情况也可以,但是为了保持简单性,我们可以在此处忽略这些行)。

基本上,您是在要求数据库选择某些内容,然后在select语句的一个字段中尝试重新选择返回多于1行的内容,这会导致错误。

您需要更改逻辑以使用联接而不是子选择。

在移动设备上,因此目前无法提供代码示例。

我设法使用@Gordon Linoff代码解决了这个问题,最终结果是:

SELECT gt.*, goods.*
FROM good_texts gt
JOIN goods ON goods.id = gt.goodid
WHERE gt.languageid = 2
UNION ALL
SELECT gt.*, goods.*
FROM good_texts gt
JOIN goods ON goods.id = gt.goodid
WHERE gt.languageid = 1 AND
      NOT EXISTS (SELECT 1
                  FROM good_texts gt2
                  WHERE gt2.goodid = gt.goodid AND gt2.languageid = 2
                 )

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM