I have this SQL query and I am getting an error.
SELECT
table1.id as id,
CONCAT( table2.first_name , ' ' , table2.last_name ) as name,
table2.country_code as country_code,
(select table3.id from table3 where table3.user_id = table1.id AND table3.description NOT LIKE '%SOMETEXTHERE%' LIMIT 1) as trans_id,
table4.important as important,
table1.status as status
FROM table1
LEFT JOIN table2 ON eid = table2.id
LEFT JOIN table4 ON table4.ewallet_transaction_id = trans_id
ORDER BY transaction_date desc;
The error is: Error Code: 1054. Unknown column 'trans_id' in 'on clause'
But the trans_id does exist.
Note: I also try other alias for 'trans_id' like 'transaction_id'
This might be an easy question but I just cant figure it out. Thanks for your help in advance.
Because your mix join syntax
To allow the join to be processed, group the first two tables explicitly with parentheses so that the operands for the ON clause are (t1,t2) and t3:
SELECT * FROM (t1, t2) JOIN t3 ON (t1.i1 = t3.i3);
Alternatively, avoid the use of the comma operator and use JOIN instead:
SELECT * FROM t1 JOIN t2 JOIN t3 ON (t1.i1 = t3.i3);
You have to use a JOIN FOR table3 too, this way
SELECT
table1.id as id,
CONCAT( table2.first_name , ' ' , table2.last_name ) as name,
table2.country_code as country_code,
table31.trans_id as trans_id,
table4.important as important,
table1.status as status
FROM table1
INNER JOIN (select id as trans_id, user_id from table3 where table3.description NOT LIKE '%SOMETEXTHERE%' GROUP BY 1) table31 ON table1.id=table31.user_id
LEFT JOIN table2 ON eid = table2.id
LEFT JOIN table4 ON table4.ewallet_transaction_id = table31.trans_id
ORDER BY transaction_date desc;
Related
I searched around and found a near example to what I'm looking for, but it doesn't work in my case.
I have a query that does an INNER JOIN on two tables and this join constrains my overall data set substantially. I then want to LEFT JOIN onto a third table but I only want one record from that third table. The reason for the left join is because not every result of the INNER JOIN has a match in the 3rd table. Something like this:
SELECT DISTINCT t1.code, t2.id, t2.code, t3.id, t3.source_title, t3.display_order
FROM table1 t1
INNER JOIN table2 t2 ON t2.code=t1.code AND t2.type=0
LEFT JOIN table3 t3 ON t3.code=t1.code
ORDER BY t1.code, t3.display_order
This query returns too many records because the third table contains multiple records with a matching code. I just want the first one that matches with the lowest display_order value and, unfortunately, I can't limit the records to have display_order=1 because the lowest display order is not always one.
IMPORTANT: The t3.id value (if any) returned by this query must correspond to the record with the lowest display_order value. I.e., it won't work if the query correctly returns the lowest display_order value but the t3.id value corresponds to some other record in table 3.
Is this even possible? Any help would be much appreciated.
EDIT: Per Nick's suggestion, I have tried this, which appears to be working. I'll do some verification and report back:
SELECT DISTINCT t1.code, t2.*, sq.id, sq.source_title, sq.display_order
FROM table1 t1
INNER JOIN table2 p ON t2.code=t1.code AND t2.type=0
LEFT JOIN (
SELECT t3.*
FROM table3 t3
WHERE t3.display_order=(
SELECT MIN(display_order)
FROM table3 t3a
WHERE t3a.code = t3.code
)
) sq ON sq.code=t1.code
ORDER BY t1.code, sq.display_order
You should be able to replace table3 in your LEFT JOIN with
(SELECT *
FROM table3 t3
WHERE display_order = (SELECT MIN(display_order)
FROM table3 t3a
WHERE t3a.code = t3.code)
) t3
In MySQL 8.0 you can try to use row_number() for each code and ordered by display_order in a subquery from table3. Then left join that result and check for the row_number() to be equal to 1.
SELECT DISTINCT
t1.code,
t2.id,
t2.code,
t3.id,
t3.source_title,
t3.display_order
FROM table1 t1
INNER JOIN table2 t2
ON t2.code = t1.code
LEFT JOIN (SELECT t3.id,
t3.source_title,
t3.display_order,
t3.code,
row_number() OVER (PARTITION BY t3.code
ORDER BY t3.display_order) rn
FROM table3 t3) t3
ON t3.code = t1.code
WHERE t2.type = 0
AND t3.rn = 1
ORDER BY t1.code,
t3.display_order;
In lower versions you can try correlated subqueries ordered by display_order and LIMIT 1 (to get only one record).
SELECT DISTINCT
t1.code,
t2.id,
t2.code,
(SELECT t3.id
FROM table3 t3
WHERE t3.code = t1.code
ORDER BY t3.display_order,
t3.id
LIMIT 1) id,
(SELECT t3.source_title
FROM table3 t3
WHERE t3.code = t1.code
ORDER BY t3.display_order,
t3.id
LIMIT 1) source_title,
(SELECT t3.display_order
FROM table3 t3
WHERE t3.code = t1.code
ORDER BY t3.display_order,
t3.id
LIMIT 1) display_order
FROM table1 t1
INNER JOIN table2 t2
ON t2.code = t1.code
WHERE t2.type = 0
ORDER BY t1.code,
(SELECT t3.display_order
FROM table3 t3
WHERE t3.code = t1.code
ORDER BY t3.display_order,
t3.id
LIMIT 1);
I assumed, that display_order in table3 isn't unique but id is. So I added id to the ORDER BY clauses in the subqueries to make sure the same record is selected in each of them. If display_order is unique, you can remove id FROM the ORDER BY clauses.
Edit:
If you don't want to repeat the subqueries in the (overall) ORDER BY clause, you can also order by the column ordinals. E.g.:
...
ORDER BY 1, 6;
i have three tables and want to run INNER JOIN and IN clause on them.
can anyone tell me where i am doing wrong
SELECT `tblinvoices`.id,`tblinvoices`.userid,`firstname`,`lastname`
FROM `tblinvoices`
WHERE `paymentmethod`IN
(SELECT `gateway` FROM `tblpaymentgateways` WHERE `setting`='type' AND `value` = 'CC')
INNER JOIN `tblclients` ON `tblinvoices`.userid=`tblclients`.id"
JOIN comes before WHERE:
SELECT tblinvoices.id,
tblinvoices.userid,
firstname,
lastname
FROM
tblinvoices
INNER JOIN tblclients
ON tblinvoices.userid = tblclients.id
WHERE
paymentmethod IN
(select gateway
FROM tblpaymentgateways
WHERE setting='type'
AND value = 'CC')
I am new to php & mysql and I'm trying to make a script that gets the distance walked with the player's name. I can get the player's walked distance with his id, but the value for the player_id is in a different table.
It looks like this:
Table1: player_id | foot (walked distance)
Table2: name | player_id
So I want to use the name by the player_id in my table.
Code
You require a simple join.
SELECT Table1.foot, Table2.name
FROM Table1
INNER JOIN Table2
ON Table1.player_id = Table2.player_id;
You just need to join both these table.
Just try this code:
$query = "SELECT T1.*, T2.name
FROM table1 T1
LEFT JOIN table2 T2 ON T1.player_id = T2.player_id
ORDER BY T2.name ASC";
For more details of JOIN: Link
Let me know for more help.
You can use
$query = "select t1.player_id, t2.name, t1.foot
from table1 t1
join table2 t2 on t1.player_id = t2.player_id"
If you want to order the player names in alphabetical order then you can additionally use order by clause
$query = "select t1.player_id, t2.name, t1.foot
from table1 t1
join table2 t2 on t1.player_id = t2.player_id
order by t2.name"
Use left join in mysql.
Suppose if you have two tables use this
SELECT T1.*,T2.walked distance
FROM table1 T1
LEFT JOIN table2 T2
ON T1.id=T2.player_id;
Click Here For more example
I have tried the following syntax, which seems to work fine on SQL when I use Oracle SQL Developer. However, when I use the code in MySQL, I get ther error "Something went wrong!".
$result = mysqli_query($con, "SELECT * FROM Table1 NATURAL JOIN (SELECT ID, SUM(row2) FROM table2 GROUP BY ID) NATURAL JOIN (SELECT ID, COUNT(col1) FROM Table2 WHERE ID IS NOT NULL GROUP BY ID)")
or die("Something went wrong!");
Is there a difference in syntax in this case, or could it be anything else I'm doing wrong?
Thanks!
This is your query:
SELECT *
FROM Table1 NATURAL JOIN
(SELECT ID, SUM(row2) FROM table2 GROUP BY ID) NATURAL JOIN
(SELECT ID, COUNT(col1) FROM Table2 WHERE ID IS NOT NULL GROUP BY ID)
MySQL supports NATURAL JOIN (I don't recommend using it, but that is another matter). Unlike Oracle, you need to have table aliases on the tables, essentially names for them. You may also need column aliases. I always use them, so I don't know if they are needed.
Try this:
SELECT *
FROM Table1 t1 NATURAL JOIN
(SELECT ID, SUM(row2) as cnt_row2
FROM table2
GROUP BY ID
) t2row NATURAL JOIN
(SELECT ID, COUNT(col1) as cnt_col1
FROM Table2
WHERE ID IS NOT NULL
GROUP BY ID
) t2col1
You can actually simplify this query:
SELECT t1.*, t2.cnt_col1, t2.cnt_row2
FROM Table1 t1 INNER JOIN
(SELECT ID, COUNT(col1) as cnt_col1, SUM(row2) as cnt_row2
FROM Table2
GROUP BY ID
) t2
ON t1.id = t2.id
The filtering on ID IS NOT NULL has no effect, because a NULL value will not be included in the join.
In MySQL all the Sub queries that are used in the FROM part need an alias name. In your case its missing. And I don't use NATURAL JOIN because using other specific INNER JOIN or LEFT JOIN clarifies the condition and scenario. So may be you could rewrite your query like this to make it work:
SELECT * FROM Table1
INNER JOIN (SELECT ID, SUM(row2) FROM table2 GROUP BY ID) a
ON a.ID = Table1.ID
INNER JOIN (SELECT ID, COUNT(col1) FROM Table2 WHERE ID IS NOT NULL GROUP BY ID) b
ON b.ID = Table2.ID;
I have the following SQL query:
SELECT * FROM `table1` INNER JOIN `table2` ON table1.messageid=table2.messageid WHERE `venue_active` = 1
The above works fine but it only returns fields where both tables have a messageid field.
My problem is that I need it to return ALL fields from Table1 reguardless if it has a messageid match in table2 or not.
So, in other words I need ALL records to be returned from Table1 and all records from Table2 where there's a messageid that matches both.
How can I do this?
Use a LEFT JOIN rather
SELECT *
FROM `table1` LEFT JOIN
`table2` ON table1.messageid=table2.messageid
WHERE `venue_active` = 1
That said, it will only work if venue_active is also part of table1, and not table2.
Have a look at the different scenarios
SQL Fiddle DEMO
Use a LEFT join rather than INNER
For example:
SELECT * FROM `table1`
LEFT JOIN `table2` ON table1.messageid=table2.messageid
WHERE `venue_active` = 1
Either you need a LEFT JOIN instead, or
a FULL OUTER JOIN workaround for MySQL:
SELECT
a.*,
b.*
FROM
table1 a
LEFT JOIN
table2 b ON a.messageid = b.messageid
WHERE a.venue_active = 1
UNION
SELECT
a.*,
b.*
FROM
table1 a
RIGHT JOIN
table2 b ON a.messageid = b.messageid;
WHERE a.venue_active = 1