Self Joins in Laravel 8 Framework - database

I'm working on this project were I'm using Laravel 8 as my backend frame work and I have to make a self Join, I have tried out this code but it did not work -the first join is the one I tried but failed- :
public function get_all_medical_centers(){
$data= DB:: table('medicalcenters')
->join('medicalcenters','medicalcenters.id',"=",'medicalcenters.parent_id')
->join('countries','medicalcenters.country_id',"=",'countries.id')
->join('states','medicalcenters.country_id',"=",'states.id')
->join('cities','medicalcenters.country_id',"=",'cities.id')
->select('medicalcenters.*', 'countries.name as country_name', 'states.name as state_name', 'cities.name as cities_name')
->get();
return $data;
}
The thing is, in the database the medical centers table has some attributes that are the parent of other attributes and I want to get the name of the parent attribute when previewing the children to also preview the name of its parent and not just the id.
the table diagram:

If you try to self-join a table then you have to give at least one of them an alias, because otherwise, SQL can't know what you are referring to if you select any column from those tables.
To add an alias to your joined table, you can do this:
DB::table('medicalcenters AS medc')
->join('medicalcenters AS self','medc.id',"=",'self.parent_id')
But this is a hacky solution and for normal relational data in Laravel, eloquent models would better.
Edit Why do you need Aliases on self joins:
If you join two tables, lets say: users join posts on users.id = posts.user_id. You have to specify the join condition. Here this is users.id = posts.user_id.
Lets modify this to a self join: users join users on users.id = users.user_id. Here the condition is not clear. Is this users.id or this users.user_id the original table or the self joined table? It's not clear how to join those two tables. So we have to give them different names aka aliases. Like this users as creators join users as subscribers on creators.id = subscribers.user_id.

Related

SQL name instead of ID in many to many relation

I am trying to make simple chat with database. So I created 2 tables:
Users (ID(PK), Name, Password)
Messages (ID(PK), senderID(FK from users), recipientID(FK from users)), text
I am really noob in SQL and I just can't write query that will return table Messages but with normal names instead of senderID and recipientID. Also I didn't find examples where 1 table uses twice, so JOIN didn't work for me, or I used it in wrong way.
SELECT US.Name as SenderName, UR.Name as RecipientName, M.text
FROM Messages M JOIN Users US ON US.ID = M.senderID
JOIN Users UR ON UR.ID = M.recipientID
Not sure if I understand your question correctly, or which db you are using but this is what I think you are looking for:
SELECT Messages.text, Users.name
FROM Messages
inner JOIN Users
ON Messages.sender_id = Users.id

SQL Joining journal tables to user tables

I have a MSSQL database with 3 tables: Journals, Customers, and UserAccounts.
I'm trying to query Journals for transactions per account manager. This table has a customer ID column that links to Customers.
The Customers table has a ACC_Manager column that links to UserAccounts via UserID.
Inside the UserAcounts table are first and last name columns.
So it would be
Select
Journal.amount,
Customer.name,
UserAccounts.first
From
Tables
where
Journal.ACC_manager = 'Matt'
I'm having issues joining the tables so I can query using UserAccounts.first. Could anybody help? Thanks
Try the following. I didn't get exact column names so don't just use this code without modifying it a bit to suit your specific needs:
SELECT
j.amount,
c.name,
u.first
FROM
Journals j
JOIN Customers c ON
c.customerID = j.customerID -- Exact column names?
JOIN UserAccounts u ON
u.UserID = c.ACC_Manager
WHERE
u.first = 'Matt'
You may also need to use LEFT JOIN as opposed to JOIN. Read up on JOINs to be sure.

How to do a simple JOIN in nette database

How can i do a very simple join in nette database, resulting in a query like this?
SELECT * FROM Book LEFT OUTER JOIN Author ON Book.author_id = Author.id
I have found endless tutorials on how to join combined with where clausules, order by, group by and what not, but not single tutorial on a simple join like this.
I forgot to specify, I use PHP, so i need something like $context->table('Book')->join('author');, but that of course doesn't work.
Question is already answerred, so I only add one note.
You can't do join using Nette Database, there is no join function. You can enforce join by referencing another table column in order for example, but it's pretty limited. If you need more complex join, you should better use Dibi instead of Nette Database.
You do not need join in this case, Nette provide you relationship between tables, so you can do something like this:
foreach($connection->table('book') as $book){
echo 'Book name: '.$book->name.'<br>'
echo 'Book autor: '.$book->author->name.'<br>'
}
I expect then in book table there is column author_id which is foreign key for author table.

PDO Join, avoid overwriting keys with the same name in the resulted array

I am doing a join with PDO like this:
SELECT users.*,images.*, sessions.*,social.*,videos.*,teams.*,achievements.*,_achievements_list.* FROM users LEFT JOIN images ON users.user_id=images.user_id LEFT JOIN sessions ON users.user_id=sessions.user_id LEFT JOIN social ON users.user_id=social.user_id LEFT JOIN videos ON users.user_id=videos.user_id LEFT JOIN teams ON users.user_id=teams.user_id LEFT JOIN achievements ON users.user_id=achievements.user_id LEFT JOIN _achievements_list ON achievements.achievement_id=_achievements_list.parent_id WHERE users.nickname = 'something'
The problem is that some tables have the same names for some columns, so in the array that PDO gives me back, many things are overwritten.
I am using this:
$statement = $this->pdo->prepare($query);
if ($statement->execute($param))
return $statement->fetchAll(PDO::FETCH_ASSOC);
return false;
PDO returns an associative array, but how do I do in order to avoid overwriting columns with the same names but from different tables?
you can use PDO::FETCH_NAMED, see https://phpdelusions.net/pdo/fetch_modes#FETCH_NAMED
it is very not recommended to use .* because :
if the table structure changes, then your column indexes change, and if you used to read by index, then Too bad.
mostly, you really dont need all the columns and therefore you will reduce the amount of data you retrieve from the server (if it is remote then it might even be meanningful)
Anyway, if you dont use .* you can use Aliases in your SQL Query
like
SELECT products.id prodId, orders.id orderId FROM Orders LEFT JOIN Products ON (prodId = orders.product_id) WHERE orderId = #oid

Replace All data in the table with relationship

I am stuck on how to replace all the data in a table that already has relationship.
I have to tables, Company and Contact. and the PrimaryKeys of these two tables are related to other tables.
Before, I do anything with Contact, I made a copy of Contact table (select * INTO ContactBK from Contact)
After I modified some data in Contact, now I like to replace all the data from ContactBK (orginal) back to Contact, but I could not.
I have tried to use Import in Server Management Studio and select "replace exists data", but it failed. I also can not delete all the data in Contact table and replace, because the ContactID is tied to others tables.
You could do a update from the ContactBAK table using a join approach. If the records are essentially the same with a few fields modified, this should work. For example:
UPDATE c SET c.FirstName = bak.FirstName FROM Contacts c
LEFT JOIN ContactsBAK bak ON c.ContactID = bak.ContactID
You'll have to modify the fields you want to update and match on the joins of course.

Resources