Syntax error in LEFT JOIN - postgresql

My query is as below:
Select
array_to_string(r.media,',') AS service_type,
array_to_string(array_agg(distinct s.state_name), ',') as primary_location
FROM contract.contract c
LEFT JOIN customer.customer_state s , contract.rights r ON s.id = ANY (r.state)
WHERE c.customer_code::text = 'YYYY'::text
group by r.state
order by c.contract_name asc;
and I'm getting:
ERROR: syntax error at or near "," LINE 44: LEFT JOIN
customer.customer_state s , contract.rights r O...
Please suggest

You can't mix explicit and implicit joins like that.
FROM contract.contract c
LEFT JOIN customer.customer_state s , contract.rights r ON
^^^
You should use explicit INNER JOIN or CROSS JOIN terms if you're going to be including LEFT JOIN terms.
The predicate for a join must always immediately follow the join, without other extras.
If you want to do a left join on multiple tables, you must chain the left joins.
FROM contract.contract c
LEFT JOIN customer.customer_state s ON (...)
LEFT JOIN contract.rights r ON (...)
Guesswork from here on in, as the original query's intent is unclear.
Perhaps you mean
FROM contract.contract c
INNER JOIN customer.customer_state s ON (...??...)
LEFT JOIN contract.rights r ON (s.id = ANY (r.state))
though I don't see any predicate that connects contract to either rights or customer_state in the original, so it's hard to guess your intent. If you actually intended a cartesian product (cross join) you'd write:
FROM contract.contract c
CROSS JOIN customer.customer_state s
LEFT JOIN contract.rights r ON (s.id = ANY (r.state))

Related

What is the left and right table for joins after the first join in SQL(postgresql?

I want to know, what constitutes as the left table and the right table after the first join.
For example:
From final_productions fp
left join things.pc p on fp.production_id = p.id
left join events.time t on fp.tx_id = t.id
left join things.car c on c.id = fp.channel_id
right join events.form f on f.production_id = p.id
left join events.trigger_alert ta on mc.cue_sheet_id = ta.id
I know for the first left join inner join things.pc p on fp.production_id = p.id the left table would be the table in the from statement which is final_productions. But what about the other joins(i.e the joins after the first join statement)? Could someone explain this, please? Thanks
The documentation says:
Parentheses can be used around JOIN clauses to control the join order. In the absence of parentheses, JOIN clauses nest left-to-right.
So
a LEFT JOIN b RIGHT JOIN c
is the same as
(a LEFT JOIN b) RIGHT JOIN c

What's the difference between these joins?

What's the difference between
SELECT COUNT(*)
FROM TOOL T
LEFT OUTER JOIN PREVENT_USE P ON T.ID = P.TOOL_ID
WHERE
P.ID IS NULL
and
SELECT COUNT(*)
FROM TOOL T
LEFT OUTER JOIN PREVENT_USE P ON T.ID = P.TOOL_ID AND P.ID IS NULL
?
The bottom query is equivalent to
SELECT COUNT(*)
FROM TOOL T
since it is not limiting the result set but rather producing a joined table with a lot of null fields for the right part of the join.
The first query is a left anti join.

Why does not adding distinct in this query produce duplicate rows?

This query was taken from a Rails application log...I'm trying to edit a massive postgresql statement I didn't write....If I don't add a distinct keyword after the SELECT, 2 duplicate rows appear for each braintree account. Why is this and is there another way to avoid having to use the distinct to avoid duplicates?
EDIT: I understand what distinct is supposed to do, the reason I'm asking is that it doesn't generate duplicates for other toy lines. By other toy lines, this query is building a "table" for a particular toy id (this specific example toys.id = 12). How do I figure out where the duplicate rows are being generated?
SELECT accounts.braintree_account_id as braintree_account_id,
accounts.braintree_account_id as braintree_account_id, format('%s %s', addresses.first_name,
addresses.last_name) as shipping_address_full_name,
users.email as email, addresses.line_1 as shipping_address_line_1,
addresses.line_2 as shipping_address_line_2, addresses.city as
shipping_address_city, addresses.state as shipping_address_state,
addresses.zip as shipping_address_zip_code, addresses.country
as shipping_address_country, CASE WHEN xy_shirt IS NULL THEN '' ELSE xy_shirt END, plans.name as plan_name, toys.sku as sku, to_char(accounts.created_at, 'MM/DD/YYYY HH24:MM:SS') as
account_created_at,
to_char(accounts.next_assessment_at, 'MM/DD/YYYY HH24:MM:SS') as account_next_assessment_at,
accounts.account_status as account_status FROM \"accounts\" INNER JOIN \"addresses\" ON
\"addresses\".\"id\" = \"accounts\".\"shipping_address_id\" AND \"addresses\".\"type\" IN
('ShippingAddress') LEFT OUTER JOIN shipping_methods ON
shipping_methods.account_id = accounts.id LEFT OUTER JOIN plans ON
accounts.plan_id = plans.id
LEFT OUTER JOIN users ON
accounts.user_id = users.id LEFT OUTER JOIN toys ON plans.toy_id = toys.id
LEFT OUTER JOIN account_variations ON accounts.id =
account_variations.account_id LEFT OUTER JOIN variations ON
account_variations.variation_id = variations.id
LEFT OUTER JOIN
choice_value_variations ON variations.id =
choice_value_variations.variation_id
LEFT OUTER JOIN choice_values ON
choice_value_variations.choice_value_id = choice_values.id LEFT OUTER
JOIN choice_types ON choice_values.choice_type_id = choice_types.id
LEFT
OUTER JOIN choice_type_toys ON choice_type_toys.toy_id = toys.id
AND choice_type_toys.choice_type_id = choice_types.id
LEFT OUTER JOIN
(SELECT * FROM crosstab('SELECT accounts.id, choice_types.id,
choice_values.presentation FROM accounts\n
LEFT JOIN account_variations ON
accounts.id=account_variations.account_id\n
LEFT JOIN variations ON account_variations.variation_id=variations.id\n
LEFT JOIN choice_value_variations ON
variations.id=choice_value_variations.variation_id\n
LEFT JOIN choice_values ON
choice_value_variations.choice_value_id=choice_values.id\n
LEFT JOIN choice_types ON choice_values.choice_type_id=choice_types.id
ORDER BY 1,2',\n 'select distinct choice_types.id
from choice_types JOIN choice_values ON choice_values.choice_type_id =
choice_types.id JOIN choice_value_variations ON
choice_value_variations.choice_value_id = choice_values.id JOIN
variations ON choice_value_variations.variation_id = variations.id JOIN choice_type_toys ON choice_type_toys.choice_type_id = choice_types.id JOIN toys ON toys.id = choice_type_toys.toy_id
where toys.id=12 ORDER
BY choice_types.id ASC')\n
AS (account_id int, xy_shirt
VARCHAR)) account_variation_view\n ON
accounts.id=account_variation_view.account_id WHERE
\"accounts\".\"account_status\" = 'active' AND
\"addresses\".\"flagged_invalid_at\" IS NULL AND \"toys\".\"id\" = 12
AND (NOT EXISTS (SELECT \"account_skipped_months\".* FROM
\"account_skipped_months\" WHERE
\"account_skipped_months\".\"month_year\" = 'JUL2016' AND
(account_skipped_months.account_id = accounts.id)))"
The purpose of using DISTINCT in a SELECT statement is to eliminate duplicate rows.

I use inner join but records are duplicating though I use "Distinct" and "Group By" in SQL Server 2008 R2 why?

This is the query when I run this it gives me duplicate records but I remove the INNER JOIN planingOrderBookHeader PLOH ON sd.StyleID=PLOH.StyleID and the column PLOH.OderBookID, it gives records without duplicating but I need records with column name PLOH.OderBookID how can I solve this problem ?
SELECT
CPO.ID
,CPO.StyleID
,cpo.CustomerPo
,PLOH.OderBookID
,cpo.Process
,CPD.Qty
,cpd.RefID
,cpd.Uom
,UM.MeshType
,PRC.Name
,STC.NewStyleno
,SD.TypeID
,itm.Name Part
,SD.ColorID
,COL.Name Color
,SD.FabricID
,FAB.Name Faric
,SHD.ItemID
,ITD.Name Item
,SHD.Image
FROM CustomerPO_Header CPO
INNER JOIN styleconfirmHeader STC ON STC.StyleID=CPO.StyleID
INNER JOIN CustomerPo_Details CPD ON CPO.ID=CPD.CusPOHeaderID
INNER JOIN StyleHeader SHD ON SHD.StyleID=CPO.StyleID
INNER JOIN StyleDetails SD ON CPO.StyleID=SD.StyleID
INNER JOIN ItemDetails itm ON SD.TypeID=itm.ID
INNER JOIN ColorDetails COL ON SD.ColorID=COL.ID
INNER JOIN ItemFabricDetails FAB ON FAB.ID=SD.FabricID
INNER JOIN UOM UM ON Um.ID=CPD.Uom
INNER JOIN ItemTypeDetails ITD ON SHD.ItemID=ITD.ID
INNER JOIN process PRC ON PRC.ID=CPO.Process
INNER JOIN planingOrderBookHeader PLOH ON sd.StyleID=PLOH.StyleID
Plz help me
It's hard to test without knowing what data you have. However you could try moving the table that is causing your duplicates into a subquery instead of a join. so something like:
SELECT
CPO.ID
,CPO.StyleID
,cpo.CustomerPo
,(SELECT PLOH.OderBookID FROM planingOrderBookHeader PLOH WHERE sd.StyleID=PLOH.StyleID) AS OderBookID
,cpo.Process
,CPD.Qty
,cpd.RefID
,cpd.Uom
,UM.MeshType
,PRC.Name
,STC.NewStyleno
,SD.TypeID
,itm.Name Part
,SD.ColorID
,COL.Name Color
,SD.FabricID
,FAB.Name Faric
,SHD.ItemID
,ITD.Name Item
,SHD.Image
FROM CustomerPO_Header CPO
INNER JOIN styleconfirmHeader STC ON STC.StyleID=CPO.StyleID
INNER JOIN CustomerPo_Details CPD ON CPO.ID=CPD.CusPOHeaderID
INNER JOIN StyleHeader SHD ON SHD.StyleID=CPO.StyleID
INNER JOIN StyleDetails SD ON CPO.StyleID=SD.StyleID
INNER JOIN ItemDetails itm ON SD.TypeID=itm.ID
INNER JOIN ColorDetails COL ON SD.ColorID=COL.ID
INNER JOIN ItemFabricDetails FAB ON FAB.ID=SD.FabricID
INNER JOIN UOM UM ON Um.ID=CPD.Uom
INNER JOIN ItemTypeDetails ITD ON SHD.ItemID=ITD.ID
INNER JOIN process PRC ON PRC.ID=CPO.Process
Of course this may have performance implications.

JPQL left outer join does unnecessary joins

I've got the following JPQL :
SELECT a.b.id, a.b.name, a.c.id,a.c.name
left join a.b left join a.c
group by a.b.id,a.b.name,a.c.id,a.c.name
now b and c are both referencing the same table.
the generated SQL is doing the left join I asked, and another join for a.b.name and a.c.name
(which is unnecessary because the left join includes the name, and it retrieves more results than expected)
how do I make the SQL generated not include the unnecessary join?
1 solution came up is not select the names and retrieve them individually by a different query.. but it's not the most elegant way I suppose..
(btw I tried selecting a.b,a.c and group by a.b,a.c but it throws ORA not a group by expression because the generated sql retrieves all rows but group by is only by ID)
and the left join is necessary since I want to allow null values.
Thanks a lot.
SELECT a.b.id, a.b.name, a.c.id,a.c.name
The above implicitly creates an inner join between a abd b,a nd another inner join between a and c. The query should be
select b.id, b.name, c.id, c.name
from A a
left join a.b b
left join a.c c
The group by clause doesn't make any sense, since you have no aggregate in your select clause. group by would be useful if you had, for example
select b.id, b.name, c.id, c.name, count(c.foo)
from A a
left join a.b b
left join a.c c
group by b.id, b.name, c.id, c.name