我有两个表:带列id和cost的货物和带列goodd、languageid和title的货物文本。所以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"的所有内容。第二个获取语言id为"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
)
您可以在子句NOT的子查询中选择不同的列goodid
和title
。。
基本上,您要求数据库选择一些内容,然后在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
)