Nested join with Eloquent - eloquent

In MySQL I can do a nested join. With Eloquent is it possible?
LEFT JOIN users_permissions (
INNER JOIN permissions
ON permissions.id = user_permissions.id_permission
LEFT JOIN permissions_feature
ON permissions_feature.id = user_permissions.id_permission_feature
) ON users_permissions.user_id = users.id
Basically, the first LEFT JOIN will works if ON matches, but it requires that INNER JOIN match too. Additionally, another LEFT JOIN is done if all works.
With Eloquent it seems not be possible, because JoinClause don't have a join() method.

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

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.

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