简体   繁体   English

PostgreSQL:左连接错误

[英]PostgreSQL: Error in left join

I am trying to join my master table to some sub-tables in PostgreSQL in a single select query. 我试图在一个选择查询中将我的主表连接到PostgreSQL中的一些子表。 I am getting a syntax error and I have the feeling I am making a terrible mistake or doing something which is not allowed. 我收到语法错误,我觉得我犯了一个可怕的错误或做了一些不允许的事情。 The code: 编码:

Select
id,
length,
other_stuff
from my_table tbl1
Left join
(
Select
id,
height
from my_table2 tbl2) tbl2 using (id)
left join
-- I get syntax error here
(
With a as (select id from some_table),
     b as (Select value from other_table)
Select id, value from a, b) tbl3 using (id)
order by tbl1.id

Can we use WITH clause in left joins sub or nested queries and Is there a better way to do this? 我们可以在左连接子或嵌套查询中使用WITH子句吗?有更好的方法吗?

UPDATE1 UPDATE1

Well, I would like to add some more details. 好吧,我想补充一些细节。 I have three select queries like this (having unique ID) and I want to join them based on ID. 我有三个这样的选择查询(具有唯一ID),我想基于ID加入它们。

Query1: 查询1:

With a as (Select id, my_other records... from postgres_table1)
     b as (select id, my_records... from postgres_table2)
     c as (select id, my_record.. from postgres_table3, b)
     Select
           id,
           my_records
     from a left join c on some_condtion_with_a
     order by 1

Second query: 第二个查询:

Select
      id, my_records
from
    (
    multiple_sub_queries_by_getting_records_from_c
    )

Third Query: 第三个查询:

With d as (select id, records.. from b),
     e as (select id, records.. from d),
     f as (select id, records.. from e)
select
      id,
      records..
from f

I tried to join them using left join . 我尝试使用left join加入它们。 The first two queries were joined successfully. 前两个查询已成功加入。 While, joining third query I got the syntax error. 虽然,加入第三个查询我得到了语法错误。 Maybe, I am complicating things thus I asked is there a better way to do it. 也许,我使事情变得复杂,因此我问有没有更好的方法来做到这一点。

Not tested, but I think you need this. 没有经过测试,但我认为你需要这个。 try: 尝试:

with a as (select id from some_table),
b as (Select value from other_table)
Select
id,
length,
other_stuff
from my_table tbl1
Left join
(
    Select
    id,
    height
    from my_table2 tbl2
) 
tbl2 using (id)
left join
(
    Select id, value from a, b
) 
tbl3 using (id)
order by tbl1.id

I've only ever seen/used WITH in the following format: 我只是以下列格式看过/使用过WITH:

WITH 
  temptablename(columns) as (query),
  temptablename2(columns) as (query),
  ...
  temptablenameX(columns) as (query)

SELECT ...

ie they come first 即他们是第一位的

You'll probably find it easier to write queries if you use indentation to describe nesting levels. 如果使用缩进来描述嵌套级别,您可能会发现编写查询更容易。 I like to make my SELECT FROM WHERE GROUPBY ORDERBY at one indent level, and then tablename INNER JOIN ON etc more indented: 我喜欢在一个缩进级别创建SELECT FROM WHERE GROUPBY ORDERBY,然后将tablename INNER JOIN ON等更多缩进:

SELECT
  column
FROM
  table
  INNER JOIN
  (
     SELECT subcolumn FROM subtable WHERE subclause
  ) myalias
  ON
    table.id = myalias.whatever
WHERE
  blah

Organising your indents every time you nest down a layer really helps. 每次嵌套图层时组织缩进确实有帮助。 By making everything that is "a table or a block of data like a table (ie a subquery)" indented the same amount you can easily see the notional order that the DB should retrieve 通过使“表或数据块(如表(即子查询)”的所有内容缩进相同的数量,您可以轻松地看到数据库应该检索的名义顺序

Move your WITHs to the top of the statement, you will still use the alias names in place in the sub sub query of course 将您的WITH移动到语句的顶部,当然您仍将在子子查询中使用别名

Looking at your query, there isn't much point in your subqueries.. You don't do any grouping or particularly complex processing of the data, you just select an ID and another column and then join it in. Your query will be simpler if you don't do this: 查看您的查询,您的子查询中没有太多要点。您不进行任何分组或特别复杂的数据处理,只需选择一个ID和另一列然后将其加入。您的查询将更简单如果你不这样做:

SELECT
  column
FROM
  table
  INNER JOIN
  (
     SELECT subcolumn FROM subtable WHERE subclause
  ) myalias
  ON
    table.id = myalias.whatever
WHERE
  blah

Instead, do this: 相反,这样做:

SELECT
  column
FROM
  table
  INNER JOIN
  subtable
  ON
    table.id = subtable.id
WHERE
  blah

You are over complicating things. 你太复杂了。 There is no need to use a derived table to outer join my_table2 . 无需使用派生表来连接my_table2 And there is no need for a CTE plus a derived table to join the tbl3 alias: 并且不需要CTE加派生表来加入tbl3别名:

Select id,
       length,
       other_stuff
from my_table tbl1
  Left join my_table2 tbl2 using (id) 
  left join (
    select st.id, ot.value
    from some_table st
       cross join other_table ot
  ) tbl3 using (id)
order by tbl1.id;

This assumes that the cross join you create with Select id, value from a, b is intended. 这假定您使用Select id, value from a, b创建的交叉连接Select id, value from a, b是预期的。

Re your updated requirements, following the same pattern. 按照相同的模式重新更新您的要求。

look for --my comments 寻找 - --my comments

With a as (Select id, my_other records... from postgres_table1)
     b as (select id, my_records... from postgres_table2)
     c as (select id, my_record.. from postgres_table3, b)
     d as (select id, records.. from b),
     e as (select id, records.. from d),
     f as (select id, records.. from e)

SELECT * FROM
(
    --your first 
    Select
      id,
      my_records
    from a left join c on some_condtion_with_a

) Q1
LEFT OUTER JOIN
(
    --your second
    Select
      id, my_records
    from
    (
      multiple_sub_queries_by_getting_records_from_c
    )

) Q2
ON Q1.XXXX = Q2.XXXX --fill this in !!!!!!!!!!!!!!!!!!!

LEFT OUTER JOIN
(
    --your third
    select
      id,
      records..
    from f

) Q3
ON QX.XXXXX = Q3.XXXX --fill this in !!!!!!!!!!!!!!!!!!!

It'll work, but it might not be the prettiest or most necessary SQL arrangement. 它会工作,但它可能不是最漂亮或最必要的SQL安排。 As both i and HWNN have said, you can rewrite a lot of these queries where you're just doing some simple selecting in your WITH.. But likely that theyre simple enough that the database optimizer can also see this and rerwite the query for you when it runs it 正如i和HWNN所说,你可以重写很多这些查询,你只是在你的WITH中做一些简单的选择..但很可能它们很简单,数据库优化器也可以看到这个并为你重新创建查询当它运行它

Just remember to code clearly, and lay your indentation out nicely to stop it tunring into a massive, unmaintainable, undebuggable spaghetti mess 只要记住要清楚地编码,并妥善地打下你的缩进,以阻止它变成一个巨大的,不可维护的,不可摧毁的意大利面条

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

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