2016-07-24 293 views
0

我有两个表:带有列ID和成本的商品以及带有goodid,languageid,title列的good_texts。所以good_texts包含良好的翻译。SQL子查询与UNION ALL查询结合使用

我有查询当前语言选择标题是否可用,并选择默认的标题,如果它不提供一个良好:

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 

但是,这并不与错误工作

被用作表达

一个子查询返回多行

我不明白为什么我的子查询返回多个行,即使它返回一行,如果它分开运行。 我的目标如何实现?

+0

,你能否告诉我们表格结构,样本数据和预期结果? – Philipp

+0

你正在使用什么数据库? MySQL和Postgres完全不同。 –

+0

我使用Postgresql – user2975535

回答

0

我已经成功地解决使用@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 
       ) 
0

条件是不工作的一个查询相同

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在子查询NOT in clause ..

+0

谢谢。我在我的问题中解决了这个问题,但它仍然不起作用 – user2975535

+0

什么意思不起作用,你有错误?向我显示错误消息 – scaisEdge

+0

错误是一样的:“作为表达式使用子查询返回的多行” – user2975535

0

select语句期望在一行数据上运行。 from和where子句将决定查询返回多少行数据(其他事情也可以,但为了保持简单,我们可以忽略这些数据)。

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

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

在手机上,所以现在不能提供代码示例。

2

要看起来像这样的查询:

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); 
+0

实际上,从我的问题中选择good_text的查询工作得很好。我坚持要把它和好桌子结合起来。但是你没有回答这个问题 – user2975535