What is the left and right table for joins after the first join in SQL(postgresql? - 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

Related

TSQL 2008 How to make columns for views unique

I have a query I am trying to save as a view but SSMS returns an error stating there are multiple columns with the same name.
I have tried to rename the affected columns as an alias but without success.
Column names in each view or function must be unique. Column name 'codemanQuestionID' in view or function 'vwBlocks' is specified more than once.
create view vwBlocks as
SELECT
LUConstructionType.codemanOptionID AS LUConstruction_codemanOptionID
, LUFascias.codemanOptionID AS LUFascias_codemanOptionID
, Block.windowsID
, LUWindows.windows
, LUWindows.codemanQuestionID AS codemanQuestion_ID
, Block.externalDoorID
, LUExternalDoor.externalDoor
, LUExternalDoor.codemanOptionID as LUExternal_codemanOptionID
FROM Block LEFT OUTER JOIN
LUOwnership ON Block.ownershipID = LUOwnership.ownershipID LEFT OUTER JOIN
LULocalAuthority ON Block.localAuthorityID = LULocalAuthority.authorityTypeID LEFT OUTER JOIN
LUConstructionType ON Block.constructionTypeID = LUConstructionType.constructionTypeID LEFT OUTER JOIN
LUTV ON Block.TVID = LUTV.TVID LEFT OUTER JOIN
LUSatellite ON Block.satelliteID = LUSatellite.satelliteID LEFT OUTER JOIN
LUPlayArea ON Block.playArea = LUPlayArea.playAreaID LEFT OUTER JOIN
LURoofCovering ON Block.roofCoveringID = LURoofCovering.roofCoveringID LEFT OUTER JOIN
LUFascias ON Block.fasciasID = LUFascias.fasciasID LEFT OUTER JOIN
LUWindows ON Block.windowsID = LUWindows.windowsID LEFT OUTER JOIN
LUExternalDoor ON Block.externalDoorID = LUExternalDoor.externalDoorID LEFT OUTER JOIN
LUcontractorInfo ON Block.contractorInfoID = LUcontractorInfo.contractorID LEFT OUTER JOIN
LUagentInfo ON Block.agentInfoID = LUagentInfo.agentID LEFT OUTER JOIN
LULandlord ON Block.LandlordID = LULandlord.landlordID LEFT OUTER JOIN
LUblockStatus ON Block.blockStatusID = LUblockStatus.blockStatusID LEFT OUTER JOIN
LUPropertyGroup ON Block.propertyGroup = LUPropertyGroup.propertyGroupID LEFT OUTER JOIN
LUCommunalBoilerType ON Block.communalBoilerType = LUCommunalBoilerType.communalBoilerID LEFT OUTER JOIN
LUExternalAreaManagedBy ON Block.externalAreaManagedBy = LUExternalAreaManagedBy.managedByID LEFT OUTER JOIN
LUgasBoilerMakeModel ON Block.CommBoilerMakeModelID = LUgasBoilerMakeModel.makeModelId LEFT OUTER JOIN
LUMaintenanceResp ON Block.maintenanceRepID = LUMaintenanceResp.maintenanceRepID
Can anybody recommend a solution please?
Thanks for any help in advance.
I'm not seeing codemanQuestionID twice. Here's some advice that has helped me a ton avoid and/or troubleshoot issues like this.
There are at least four ways to alias a column:
(expression) AS ((alias))
((alias)) = (expression)
WITH ((cte name)) ((alias1), (alias2),...
FROM ((subquery)) AS ((alias1>),(alias2,...
AS is the worst IMO. Its sloppy and confusing, especially when you don't include AS. The aliasing style I usually go with is:
SELECT
col1 = <expression>,
col2 = <expression>,
colABC = <expression>
FROM schema.table1 AS t1
JOIN schema.table2 AS t2;
This has made debugging waaay easier.

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.

Syntax error in LEFT JOIN

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

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