根据表值合并两列

时间:2017-01-12 23:48:02

标签: postgresql join merge union

我正在尝试将法语字符串(语言ID 1)合并到一列中。到目前为止,我能够在table1.titletable2.translated_topic中获得法语字符串,但我不确定如何连接它们。

Ver:Postgres 9.6.0

源表架构:

表1:knowledgebase_topics

id | title            | language_id |
------------------------------------
64   | The Topic      |    91       |  
65   | The Topic 2    |    91       |           
62   | Le fav sujet   |     1       |          
63   | Le fav sujet 2 |     1       |          
61   | le bonjour     |     1       |     

表2:knowledgebase_topics_translations

id | translated_topic| knowledgebase_topic_id | language_id |
-------------------------------------------------------------
   | Le sujet        |          64            |     1       | 
   | Le sujet 2      |          65            |     1       |
   | Fav The Topic   |          62            |     91      |
   | Fav The Topic 2 |          63            |     91      |

给出以下查询:

SELECT title, translated_topic, "kbt".language_id, "kbtt".language_id
FROM knowledgebase_topics as "kbt" 
LEFT JOIN knowledgebase_topics_translations as "kbtt" on ("kbtt".knowledgebase_topic_id = "kbt".id) 
INNER JOIN knowledgebase_topics_organizations as "kbto" on ("kbto".knowledgebase_topic_id = "kbt".id) 
WHERE "kbto"."organization_id" = 1 
AND to_tsvector("kbt".title) @@ to_tsquery('le') 
OR to_tsvector("kbtt".translated_topic) @@ to_tsquery('le') 
AND "kbt".language_id = 1 
OR "kbtt".language_id = 1;

我得到以下结果:

     title      | translated_topic | language_id | language_id 
----------------+------------------+-------------+-------------
 The Topic      | Le sujet         |          91 |           1
 The Topic 2    | Le sujet 2       |          91 |           1
 Le fav sujet   | Fav The Topic    |           1 |          91
 Le fav sujet 2 | Fav The Topic 2  |           1 |          91
 le bonjour     |                  |           1 |     

所需结果: table1.titletable2.translated_topics已基于language_id == 1合并。两个表都有一个语言ID列。

     title      | language_id
----------------+--------------
 Le sujet       | 1
 Le sujet 2     | 1
 Le fav sujet   | 1
 Le fav sujet 2 | 1
 le bonjour     | 1

我该怎么做?

注意:我不只是想检查lang IDs = 1,例如

and "kbt".language_id = 1 AND (instead of OR) "kbtt".language_id = 1;

因为这导致2个语言ID 1的table 2缺少记录:

     title      | translated_topic | language_id | language_id 
----------------+------------------+-------------+-------------
 Le fav sujet   | Fav The Topic    |           1 |          91
 Le fav sujet 2 | Fav The Topic 2  |           1 |          91
 le bonjour     |                  |           1 |          

所以,我已经开始工作......但这是否具有效果?

SELECT title, "kbt".language_id
FROM knowledgebase_topics as "kbt" 
INNER JOIN knowledgebase_topics_organizations as "kbto" on ("kbto".knowledgebase_topic_id = "kbt".id) 
WHERE "kbto"."organization_id" = 1
AND to_tsvector("kbt".title) @@ to_tsquery('le') 
AND "kbt".language_id = 1 
UNION ALL
SELECT translated_topic, "kbtt".language_id 
FROM knowledgebase_topics_translations as "kbtt"
INNER JOIN knowledgebase_topics_organizations as "kbto" on ("kbto".knowledgebase_topic_id = "kbtt".id) 
WHERE "kbto"."organization_id" = 1
AND to_tsvector("kbtt".translated_topic) @@ to_tsquery('le')
AND "kbtt".language_id = 1;

提供输出:

     title      | language_id 
----------------+-------------
 le bonjour     |           1
 Le fav sujet   |           1
 Le fav sujet 2 |           1
 Le sujet       |           1
 Le sujet 2     |           1
(5 rows)

1 个答案:

答案 0 :(得分:2)

设置回答问题的环境

首先,观察我们如何用简洁的DDL最好地描述问题。最好在将来,你将学习如何写这样的问题..

CREATE TEMPORARY TABLE knowledgebase_topics AS
SELECT * FROM ( VALUES
  (64,'The Topic',91),
  (65,'The Topic 2',91),
  (62,'Le fav sujet',1),
  (63,'Le fav sujet 2',1),
  (61,'le bonjour',1)
) AS t(knowledgebase_topic_id, title, language_id);

CREATE TEMPORARY TABLE knowledgebase_topics_translations AS
SELECT * FROM ( VALUES
  ('Le sujet'       ,64,1  ),
  ('Le sujet 2'     ,65,1  ),
  ('Fav The Topic'  ,62,91 ),
  ('Fav The Topic 2',63,91 )
) AS t(translated_topic, knowledgebase_topic_id, language_id);

然后你只需要告诉我们你想要什么,我们就可以轻松地找到工作环境并回答你的问题。不需要英语!我们两个人都比较容易。

解决方案

我们在UNION ALL中使用SELECT将其包装在language中,以便我们可以按ID排序,并轻松地在一个地方更改您要查找的SELECT title, language_id FROM ( SELECT knowledgebase_topic_id, title, language_id FROM knowledgebase_topics UNION ALL SELECT knowledgebase_topic_id, translated_topic, language_id FROM knowledgebase_topics_translations ) AS t(id, title, language_id) WHERE language_id = 1 ORDER BY id;

     title      │ language_id 
────────────────┼─────────────
 le bonjour     │           1
 Le fav sujet   │           1
 Le fav sujet 2 │           1
 Le sujet       │           1
 Le sujet 2     │           1
(5 rows)

输出

MakeTheSprocFailWhenCalled();
try 
{
    ExecuteSomethingThatCallsASproc();
    throw new Exception();
    Assert.Fail("Should never have made it here");
}
catch(Exception e)
{
    Assert.AreEqual(typeof(SqlException), e.GetType());
}
finally
{
    UndoTheThingIDidInTheFirstLine();
}