2017-06-14 137 views
1

我想在單個select查詢中將我的主表連接到PostgreSQL中的某些子表。我遇到了一個語法錯誤,我感覺我犯了一個可怕的錯誤,或者做了一些不允許的事情。代碼:PostgreSQL:左連接錯誤

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 

我們能用子句中使用左聯接子或嵌套查詢,是否有更好的方法來做到這一點?

UPDATE1

嗯,我想補充一些更多的細節。我有三個像這樣的選擇查詢(具有唯一ID),我想根據ID加入它們。

查詢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 

第二個查詢:

Select 
     id, my_records 
from 
    (
    multiple_sub_queries_by_getting_records_from_c 
    ) 

第三個查詢:

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 

我試着用left join加入他們的行列。前兩個查詢已成功加入。雖然,加入第三個查詢我得到了語法錯誤。也許,我正在複雜的事情,因此我問是否有更好的方式來做到這一點。

+1

'選擇ID,從價值,B'創建一個交叉連接A'和'B'之間'(這樣的橫'some_table'和'other_table'之間加入)。那真的是你想要的嗎? –

+0

我已經添加了我的要求。 –

回答

1

您是在複雜的事情。沒有必要使用派生表來加入​​。而且也沒有必要的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; 

這假設交叉連接創建具有Select id, value from a, b意。

+0

請參閱編輯。我試圖更詳細地描述我的情況。綜上所述,我想加入的第二和第三查詢到第一的結果,但有多個子查詢,在我的結構派生表。 –

1

未經測試,但我認爲你需要這個。嘗試:

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 
1

我只看過/所使用的格式如下:

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

SELECT ... 

即它們是第一位的

您可能會發現更容易編寫查詢,如果你使用縮進來描述嵌套層次。我喜歡讓我選擇WHERE GROUPBY ORDERBY在一個縮進級別,然後表名INNER JOIN ON等多個縮:

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

每次整理您的縮進你窩,往下一層確實有幫助。通過將所有「表格或數據塊(如子表)」的所有內容縮進相同的數量,您可以輕鬆地看到數據庫應該檢索的名義順序

將您的WITHs移動到頂部聲明,您仍然可以在子查詢當中使用別名名稱

查看您的查詢,您的子查詢沒有太多意義。您不需要進行任何分組或特別複雜的處理數據,你只需選擇一個ID和另一列,然後加入它。如果你不這樣做,你的查詢將會更簡單:

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

相反,這樣做:

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

非常感謝爲您詳細介紹。我添加了我想要加入的三個查詢的結構。在我的代碼中有多個嵌套查詢和分組。 –

0

重新更新的要求,遵循相同的模式。

--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 !!!!!!!!!!!!!!!!!!! 

它會工作,但它可能不是最漂亮或最必要的SQL的安排。由於i和HWNN說,你可以重寫很多這些查詢,你只是在做一些簡單的選擇你的用..但是可能嗎更有足夠簡單,數據庫優化也可以看到這一點,rerwite查詢適合你當它運行它

只記得清楚的代碼,並躺在你縮進了很好地阻止它tunring成塊狀,難以維護,undebuggable意大利麪條混亂