the MYSQL query below combines a number of tables. However, as you can see, I would like to add a LEFT JOIN at the end on the receipt table. The query returns an error when I add the LEFT JOIN. Anybody know the best way to LEFT JOIN the receipt table to the rest of the query. Sorry if this is a newbie question. Thanks !!
SELECT user_name, expense_category, merchant_name, expense_cost, expense_date, expense_status, receipt_image, expense_comment
FROM users, expenses, merchants, receipts
WHERE ".$adminId." = expenses.admin_id
AND expenses.user_id = users.user_id
AND expenses.merchant_id = merchants.merchant_id
AND LEFT JOIN (receipts)
ON expenses.receipt_id = receipts.receipt_id
Here is a clean approach of doing it, note that I have added alias for the tables for better readability so you may use the alias name in the select statement to fetch the column from the proper table.
SELECT
u.user_name,
ex.expense_category,
mer.merchant_name,
ex.expense_cost,
ex.expense_date,
ex.expense_status,
re.receipt_image,
ex.expense_comment
FROM users u
JOIN expenses ex on ex.user_id = u.user_id
JOIN merchants mer on mer.merchant_id = ex.merchant_id
LEFT JOIN receipts re on re.receipt_id = ex.receipt_id
where
ex.admin_id = '$adminId'
Try this,
SELECT user_name, expense_category, merchant_name, expense_cost, expense_date, expense_status, receipt_image, expense_comment
FROM users, expenses, merchants, receipts
LEFT JOIN receipts ON expenses.receipt_id = receipts.receipt_id
WHERE ".$adminId." = expenses.admin_id
AND expenses.user_id = users.user_id
AND expenses.merchant_id = merchants.merchant_id
Use join clauses instead of where clause. I.e.
SELECT user_name, expense_category, merchant_name, expense_cost, expense_date, expense_status, receipt_image, expense_comment
FROM users
INNER JOIN expenses on users.user_id = expenses.expenses_id
INNER JOIN merchants on merchants.merchant_id = expenses.merchant_id
LEFT JOIN (receipts)
ON expenses.receipt_id = receipts.receipt_id
WHERE ".$adminId." = expenses.admin_id
Note that any columns from the receipts will be NULL in the select statement whenever there's no matching record.
Related
I have two tables (msg and users). I am trying to join these two tables together and print out the first and last name of the sender and the recipient as well as all of the message content if the message is marked as flag. I keep getting errors though, and have not found a good way to do this yet.
Pictures of tables for reference: https://imgur.com/a/wYuptfR
SQL query I'm using right now:
SELECT msg.*, users.uuid AS users.ruuid, users.uuid AS users.suuid, users.firstName, users.lastName
FROM msg
INNER JOIN users ON users.ruuid = msg.recipient
AND INNER JOIN users ON users.suuid = msg.sender
WHERE msg.flag = 0
You can query the same table several times if you use different aliases. Also, note you shouldn't have an and between the two join clauses:
SELECT msg.*,
r.uuid AS ruuid, r.firstName AS rfirstname, r.lastName AS rlastname,
s.uuid AS suuid, s.firstName AS sfirstname, s.lastName AS slastname
FROM msg
INNER JOIN users r ON r.uuid = msg.recipient
INNER JOIN users s ON s.uuid = msg.sender
WHERE msg.flag = 0
Try This
SELECT msg.*, u.uuid , u.firstName, u.lastName, s.uuid , s.firstName, s.lastName
FROM msg
INNER JOIN users u ON u.uuid = msg.recipient
INNER JOIN users s ON s.uuid = msg.sender
WHERE msg.flag = 0
I have three tables: users (id), projects (id_project, owner_id) and followers (repo_id, user_id). I would like count how many followers one project has. I would like to return all user projects, with and without followers.
Where:
id = owner_id = user_id
id_project = repo_id
I report more than 1,000 users in my query. I did this:
rs = dbSendQuery(mydb, "select p.id_project, p.owner_id, count(f.user_id) from users u left outer join projects p on p.owner_id = u.id and u.id in (123, 526, 852) left outer join followers f on p.id_project = f.repo_id group by p.id;")
The query is too slow. Could anyone give me any suggestions to make the query faster? Am I doing something wrong?
Maybe, I can break into two queries, but how do I get the result of the first (which are the projects of the users) and add in the second query (where I would have the number of followers of the projects) in R?
I am using R and mysql.
Regards,
Thaciana
Sometimes switching to a correlated subquery can speed such queries:
select p.id_project, p.owner_id, count(f.user_id)
from users u left outer join
projects p
on p.owner_id = u.id and u.id in (123, 526, 852) left outer join
followers f
on p.id_project = f.repo_id
group by p.id;
For this query, you want indexes on users(id), projects(owner_id, id_project), and followers(repo_id, user_id).
I note that you are not really using the users table. So, this should do what you want:
select p.id_project, p.owner_id, count(f.user_id)
from projects p left outer join
followers f
on p.id_project = f.repo_id
where p.owner_id in (123, 526, 852)
group by p.id;
The same indexes should work on this query, although the one on users is obviously not needed.
Next, in MySQL, correlated subqueries are sometimes faster than aggregation queries. So, you can try:
select p.id_project, p.owner_id,
(select count(*)
from followers f
where p.id_project = f.repo_id
) as num_followers
from projects p
where p.owner_id in (123, 526, 852);
I am stuck with some SQL query.
I have four tables. Which are connected:
user =>user_account=>acount_profile_entries=>profile_entries
From left to right they are one to many.
user_account has a user_id field as FK.
account_profile_field has user_account_id and profile_entry_id.
Profile_entries has a text field that I need to show for each user (account).
I need to write a query that will show me, all accounts for every user, and its profile entries.
I am sorry if this is confusing, I tried to make it simple
This is what I have done so far. I can show all accounts for every user and this is the point I am stuck with. Last two commented out Joins are not working properly. I believe I am close somewhat, I just need a push :)
SELECT
u.email AS Email,
u.id AS UserId,
ua.id AS UserAccountId,
ua.app_id AS Application
FROM users AS u
INNER JOIN user_accounts ua ON ua.user_id = u.id
-- INNER JOIN account_profile_entries ape ON ape.user_account_id = ua.id
-- INNER JOIN profile_entries as pe ON pe.id = ape.profile_entry_id
limit 10
Try this SQL Query with using LEFT JOIN
Description :- The MySQL LEFT JOIN joins two tables and fetches rows based on a condition, which is matching in both the tables and the unmatched rows will also be available from the table written before the JOIN clause.
SYNTAX
SELECT column_name(s)
FROM table1
LEFT JOIN table2 ON table1.column_name = table2.column_name;
SELECT u.*,
u.id AS UserId,
ua.id AS UserAccountId,
ua.app_id AS Application,pe.* FROM `users` u
LEFT JOIN user_accounts ua ON ua.user_id = u.id
LEFT JOIN account_profile_entries ape ON ape.user_account_id = ua.id
LEFT JOIN profile_entries as pe ON pe.id = ape.profile_entry_id LIMIT 10
I'm trying to get MySQL to return me all instructors who don't have a booking at a certain time. This query is essentially the search query. So return all instructors and their details that aren't already booked basically. Could someone help me finish it off?
SELECT
AddressTypes.AddressTypeName,
Addresses.*,
InstructorSettings.*,
Users.*,
BookedSlots.DateTime
FROM Users
LEFT OUTER JOIN InstructorSettings
ON Users.UserID = InstructorSettings.UserID
LEFT OUTER JOIN Addresses
ON Users.UserID = Addresses.UserID
INNER JOIN AddressTypes
ON Addresses.AddressTypeID = AddressTypes.AddressTypeID
LEFT OUTER JOIN BookedSlots
ON Users.UserID = BookedSlots.UserID
WHERE Users.AccountTYpe = 3 AND Addresses.PostCode1 IN ('l13') AND BookedSlots.DateTime <> '2013-04-25 11:00:00'
The query above doesn't return anything, but if I take out the "AND BookedSlots.DateTime <> '2013-04-25 11:00:00'" it returns all the instructors details fine.
Database
It looks to me as if what you're looking for is the lack of existence of records in BookedSlots for the specified time.
I'm not sure if this is considered MySQL best practices, but I typically accomplish that task not with a join, but with a sub-select or a temp table, like so:
SELECT
AddressTypes.AddressTypeName,
Addresses.*,
InstructorSettings.*,
Users.*,
FROM Users
LEFT OUTER JOIN InstructorSettings
ON Users.UserID = InstructorSettings.UserID
LEFT OUTER JOIN Addresses
ON Users.UserID = Addresses.UserID
INNER JOIN AddressTypes
ON Addresses.AddressTypeID = AddressTypes.AddressTypeID
WHERE Users.AccountType = 3 AND Addresses.PostCode1 IN ('l13')
AND Users.UserID not in (SELECT BookedSlots.InstructorID FROM BookedSlots
WHERE BookedSlots.DateTime = '2013-04-25 11:00:00')
EDIT: per comments, changed the select statement to disclude BookedSlots, and the sub-select to return InstructorId (which matches instructors instead of students on the booking).
To check that there aren't any bookings on a particular timeslot, include the timeslot in the join conditions and select where the timeslot id is null - like so:
SELECT
AddressTypes.AddressTypeName,
Addresses.*,
InstructorSettings.*,
Users.*,
BookedSlots.DateTime
FROM Users
LEFT OUTER JOIN InstructorSettings
ON Users.UserID = InstructorSettings.UserID
LEFT OUTER JOIN Addresses
ON Users.UserID = Addresses.UserID
INNER JOIN AddressTypes
ON Addresses.AddressTypeID = AddressTypes.AddressTypeID
LEFT OUTER JOIN BookedSlots
ON Users.UserID = BookedSlots.UserID AND
BookedSlots.DateTime = '2013-04-25 11:00:00'
WHERE Users.AccountTYpe = 3 AND
Addresses.PostCode1 IN ('l13') AND
BookedSlots.UserID is null
Suppose we have this model:
As you see industry_id can be null. Can I fetch industry.name (if any), user.description, profile.name and project.title (all project titles) he/she has with a single MySQL query while having user.id?
Yes, JOIN the two tables:
SELECT
i.name,
u.id
FROM Industry AS i
LEFT JOIN `User` AS u ON u.industry_id = i.industry_id;
Update:
For multiple tables:
SELECT
i.Name AS InustryName,
p.Name AS UserName,
u.Description,
j.title AS ProjectTitle
FROM Industry AS i
INNER JOIN User AS u ON i.id = u.id
INNER JOIN Profile AS p ON p.user_id = u.id
INNER JOIN Project AS j ON u.id = j.user_id;
Note that: I used INNER JOIN between the tables, this will give you only the matched rows from the joined tables, you might need to use LEFT JOIN instead of innner join to include the untmatched rows, i.e., to get those industries that has no entries in the other tables. See this blog post:
A Visual Explanation of SQL Joins