MySQL join a table to another table only if [duplicate] - mysql

This question already has answers here:
conditional join in mysql
(4 answers)
Closed 6 years ago.
I have a little complicated query here. I have to select columns by names cant just user 'orders.*. because i have multiple columns from different tables with the same name.
What I'm trying to do is to select specific fields from orders,users,payment_methods_translation and join bank_accounts_translation only if the orders.payment_method_id = '3'
SELECT
orders.id as orderid,
orders.final_total,
orders.user_id,
orders.auto_cancel,
users.id as userid,
users.first_name,
payment_methods_translation.payment_method_id,
payment_methods_translation.name
FROM
orders,users,
payment_methods_translation
WHERE
orders.id='$id' AND
orders.user_id = users.id AND
orders.payment_method_id = payment_methods_translation.payment_method_id AND
orders.auto_cancel='1'
JOIN
bank_accounts_translation ON (orders.payment_method_id='3'
AND orders.bank_id = bank_accounts_translation.bank_account_id)
But I get a mysql error. So how can I select all the fields from bank_accounts_translation only if orders.payment_method_id = '3' and orders.bank_id = bank_accounts_translation.bank_id

Left join should do it... I
Refactored the code to use the current ANSI standards, you appear to be mixing them.
used table aliases to improve readability.
LEFT JOIN says return all records from prior listed tables and only those that match the on criteria of the table being joined to.
SELECT O.id as orderid
,O.final_total
,O.user_id
,O.auto_cancel
,u.id as userid
,u.first_name
,PMT.payment_method_id
,PMT.name
FROM orders O
INNER JOIN users U
ON O.user_id = U.id
INNER JOIN payment_methods_translation PMT
ON O.payment_method_id = PMT.payment_method_id
LEFT JOIN bank_accounts_translation BAT
ON O.payment_method_id='3'
and O.bank_id = BAT.bank_account_id
WHERE O.id='$id'
and O.auto_cancel='1'

Related

SQL Left Join a Table on a Left Joined Table

Iam currently trying to left join a table on a left joined table as follows.
I have the tables:
accounts (id, vorname, nachname)
projektkurse (id, accounts_id, projektwochen_id)
projektkurs_einzel (id, projektkurse_id)
projektkurs_einzel_zeiten (id, date, shift, projektkurs_einzel_id)
Now I want to get every account and the amount times they have an entry inside of projektkurs_einzel_zeiten, which should also be unique. So having the same date and shift multiple times does not count as multiple entries. The result should also be limited by the column projektwochen_id from the table projektkurse. This column should match a certain value for example 8.
Some Accounts don't have any entries in projektkurse, projektkurs_einzel and projektkurs_einzel_zeiten, this is why my first thought was using LEFT JOIN like this:
SELECT accounts.id, accounts.vorname, accounts.nachname, COUNT(DISTINCT projektkurs_einzel_zeiten.date, projektkurs_einzel_zeiten.shift) AS T
FROM accounts
LEFT JOIN projektkurse on accounts.id = projektkurse.creator_id
LEFT JOIN projektkurs_einzel on projektkurse.id = projektkurs_einzel.projektkurs_id
LEFT JOIN projektkurs_einzel_zeiten ON projektkurs_einzel.id = projektkurs_einzel_zeiten.projektkurs_einzel_id
WHERE projektkurse.projektwochen_id = 8
GROUP BY accounts.id
This query does not achieve exactly what I want. It only returns accounts that have atleast one entry in projektkurse even if they have none in projektkurs_einzel and projektkurs_einzel_zeiten. The Count is obviously 0 for them but the accounts that have no entries in projektkurse are being ignored completly.
How can I also show the accounts that don't have entries in any other table with the Count 0 aswell?
I would recommend writing the query like this:
SELECT a.id, a.vorname, a.nachname,
COUNT(DISTINCT pez.date, pez.shift) AS T
FROM accounts a LEFT JOIN
projektkurse
ON a.id = pk.creator_id AND
pk.projektwochen_id = 8 LEFT JOIN
projektkurs_einzel pe
ON pk.id = pe.projektkurs_id LEFT JOIN
projektkurs_einzel_zeiten pez
ON pe.id = pez.projektkurs_einzel_id
GROUP BY a.id, a.vorname, a.nachname;
Notes:
Your problem is fixed by moving the WHERE condition to the ON clause. Your WHERE turns the outer join into an inner join, because NULL values do not match.
Table aliases make the query easier to write and to read.
It is a best practice to include all unaggregated columns in the GROUP BY. However, assuming that id is unique, your formulation is okay (due to something called "functional dependencies").
You should not use eft join table's column ins where condition this work as inner join
You should move the where condition for a left joined table in the corresponding ON clause
SELECT accounts.id, accounts.vorname, accounts.nachname, COUNT(DISTINCT projektkurs_einzel_zeiten.date, projektkurs_einzel_zeiten.shift) AS T
FROM accounts
LEFT JOIN projektkurse on accounts.id = projektkurse.creator_id
AND projektkurse.projektwochen_id = 8
LEFT JOIN projektkurs_einzel on projektkurse.id = projektkurs_einzel.projektkurs_id
LEFT JOIN projektkurs_einzel_zeiten ON projektkurs_einzel.id = projektkurs_einzel_zeiten.projektkurs_einzel_id
GROUP BY accounts.id

join nested queries in from clause

Can you tell me what I need to manipulate in this query to get it working?
select C.ID from
(select A.ID from CUSTOMERS A inner join PROFILES B on A.ID=B.ID where CTR='67564' and CST_CD in
('G','H')) as C
inner join
(select ID from RELATION_CODES where R_CD='KC') as R
on C.ID=R.ID
The individual inner queries are working just fine and giving correct results, not sure what is the problem with inner join in from clause..
Not completely sure I'm understanding your question, but this should be able to be rewritten without the subqueries:
select c.id
from customers c
join profiles p on c.id = p.id
join relation_codes rc on rc.id = c.id
where ctr = '67564'
and cst_cd in ('G','H')
and rc.r_cd = 'KC'
If this isn't working, please provide your table structure and sample data and expected results. This should get you pretty close though.
I have to ask, is the id field in the relation_codes table and the profiles table the same as the id in the customers table. Perhaps you need to identify how your tables are related.
A Visual Explanation of SQL Joins

Difference between two sql queries (using join and without join) [duplicate]

This question already has answers here:
Difference between these two joining table approaches?
(4 answers)
Closed 8 years ago.
I have two set of sql queries. Both produces the desired result for me but I am not sure which one is efficient and how. Please anybody can explain it to me?
Query 1:
SELECT
od.id, od.order_id, c.firstname, od.category, od.quantity,
od.price, o.order_date, u.username
FROM
orders o inner join order_detail od on o.id=od.order_id
join customer c on c.customerid = o.customer_id
join users u on u.userid = o.issued_by;
Query 2:
SELECT
od.id, od.order_id, c.firstname, od.category, od.quantity,
od.price, o.order_date, u.username
FROM
order_detail od, customer c, orders o,
users u WHERE o.id = od.order_id
AND o.customer_id = c.customerid
AND u.userid = o.issued_by;
The first query is the better one with the appropriate syntax. The second query is an "old school" version and should not be used.
In term of performance there is an important difference between both queries, the first one will filter the result directly during the jointure clauses. The second query will get the entire data before applying the WHERE clause on them.
Don't hesitate, choose the first version without any doubt.
Hope that this will help you.

MySQL join, even when 0 [duplicate]

This question already has answers here:
What is the difference between "INNER JOIN" and "OUTER JOIN"?
(28 answers)
Closed 8 years ago.
Im doing the follwing, to create an user report
SELECT b.username, b.name, b.permissiontoedit, a.total, a.user
FROM (SELECT user, Count( * ) AS total
FROM products
GROUP BY user)a
JOIN user b ON a.user = b.username
This should give a table with the username, full name, permision (1/0) and the total of entries.
Sadly, the query does only list users, which made more 1 or more entries in the table products. But i want all users, and if the have not made any entries in products it should display 0 or nothing.
where do i made a mistake?
Using a LEFT JOIN you can get your result:
SELECT
u.username, u.name, u.permissiontoedit, COUNT(p.user) as total
FROM
user u
LEFT JOIN
products p
ON
u.username = p.user
Note: COUNT(expression) counts only NOT NULL rows in contrast to COUNT(*) that counts every row.

#1241 - Operand should contain 1 column(s) MYSQL [duplicate]

This question already has answers here:
MySQL - Operand should contain 1 column(s)
(10 answers)
Closed 8 years ago.
I am trying to get data from the database like that, but i have this error how can i fix?
SELECT post.text,users.name,users.surname,users.profile_id,post.post_id,comments.text as comment,
(SELECT user.name, user.surname FROM users user WHERE profile_id = comments.profile_id) as name_comment
FROM post
INNER JOIN users ON users.profile_id = post.profile_id
INNER JOIN comments ON comments.profile_post = post.post_id
Simply JOIN to the users table twice
SELECT
post.text,
userpost.name,
userpost.surname,
userpost.profile_id,
post.post_id,
comments.text as comment,
usercomment.name, usercomment.surname -- this
FROM post
INNER JOIN users userpost ON userpost.profile_id = post.profile_id
INNER JOIN comments ON comments.profile_post = post.post_id
INNER JOIN users usercomment ON comments.profile_id = usercomment.profile_id
try this
SELECT post.text,users.name,users.surname,users.profile_id,post.post_id,comments.text as comment
FROM post
INNER JOIN users ON users.profile_id = post.profile_id
INNER JOIN comments ON comments.profile_post = post.post_id
WHERE profile_id = comments.profile_id
Your subquery:
(SELECT user.name, user.surname
FROM users user
WHERE profile_id = comments.profile_id) as name_comment
has 2 fields instead one
You can:
Use 2 distinct subquery to get user.name and user.surname;
concatenate the two information so you have one output field;
Why you use subquery when you have joined your users table in the main query (with the same condition)