Codeigniter/PHP Outer JOIN Syntax on Multiple Tables - php

I am trying to perform an outer JOIN 3 tables based on the "site_id" column in each table. I'm using Codeigniter/Active Record.
The user enters a site number via a form and once the number is submitted it should call the model that executes something like this:
$site_id = $this->input->post('site_id');
$this
->db
->select('*')
->where('site_id', $site_id)
->from('sites')
->join('leader', 'sites.site_id = leader.site_id', 'outer')
->join('state', 'sites.site_id = state.site_id', 'outer');
$q = $this->db->get();
However I get the following error message:
"Error Number: 1064
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'OUTER JOIN leader ON sites.site_id = leader.site_id OUTE' at line 3
SELECT * FROM (sites) OUTER JOIN leader ON sites.site_id = leader.site_id OUTER JOIN state ON sites.site_id = state.site_id WHERE site_id = '63'
Filename: /home2/cdowney/public_html/mclinbase.com/models/viewsite_model.php
Line Number: 33"
I believe(hope) this is just a small syntax error that I'm missing or a misuse of the outer join but I have not been able to figure it out.
Any guidance?

Try this -
$this->db->select('*');
$this->db->where('sites.site_id', $site_id);
$this->db->from('sites');
$this->db->join('leader', 'sites.site_id = leader.site_id', 'outer');
$this->db->join('state', 'sites.site_id = state.site_id', 'outer')
$q = $this->db->get();

Simply union select the left and right join to get the same result as outer join:
SELECT * FROM table1
LEFT JOIN table2 ON table1.id = table2.id
UNION
SELECT * FROM table1
RIGHT JOIN table2 ON table1.id = table2.id
Maybe this will help.

Related

How can I write this SQL query in Laravel by Left Join, count and group by?

The database has "orders" and "customers" tables.
I can't connect them to this usgbu request.
SELECT orders.serial_number,
count(orders.order_id) as count ,
customers.customer_name FROM orders
LEFT JOIN customers ON
orders.customer_id = customers.customer_id
GROUP By orders.serial_number;
The code I wrote is as follows:
$orders = Orders::select("orders.serial_number","customers.customer_name", DB::raw("COUNT(orders.order_id) as count"))
->leftJoin('customers','orders.customer_id','=','customers.customer_id')
->groupBy('orders.serial_number')
->get();
An error message appears as follows:
SQLSTATE[42000]: Syntax error or access violation: 1055 'alqorshop.customers.customer_name' isn't in GROUP BY (SQL: select `orders`.`serial_number`, `customers`.`customer_name`, COUNT(orders.order_id) as count from `orders` left join `customers` on `orders`.`customer_id` = `customers`.`customer_id` group by `orders`.`serial_number`)
The correct query for this sql is:
SELECT orders.serial_number,
customers.customer_name,
count(orders.order_id) as count
FROM orders
LEFT JOIN customers ON
orders.customer_id = customers.customer_id
GROUP By orders.serial_number,customers.customer_name;
OR
SELECT orders.serial_number,
count(orders.order_id) as count
FROM orders
LEFT JOIN customers ON
orders.customer_id = customers.customer_id
GROUP By orders.serial_number;
You did not include "customers.customer_name" in your group by clause which is why it's giving an error.
Either add customers.customer_name to your group by query or remove customers.customer_name from select statement
Your query is not correct -- you need to add customers.customer_name to the GROUP BY clause or remove it from the SELECT clause

MySQL Inner Join query giving errors

I have two Tables - char_items and items. item_id is a common field among the two tables.
I want read the item_id from 'char_items' table and use that to obtain other information from the 'items' table based on that item_id. But my query is showing up as incorrect in MySQL. Please help --
SELECT * FROM `char_items` WHERE char_id=$char_id && isSlotted=1 INNER JOIN `items` ON char_items.item_id=items.item_id
I keep getting the message:
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'INNER JOIN `items` ON char_items.item_id=items.item_id
LIMIT 0, 30' at line 1
Joins need to happen before the where clause
SELECT *
FROM char_items c
INNER
JOIN items i
ON c.item_id = i.item_id
WHERE char_id = $char_id
AND isSlotted = 1
where should be after join clause as like below.
SELECT * FROM `char_items` INNER JOIN `items` ON char_items.item_id=items.item_id WHERE char_id=$char_id && isSlotted=1;

You have an error in your SQL syntax; check the manual

You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'WHERE j.id_customer = 1' at line 4
SELECT j.`id_customer`, j.`id_order`, m.`id_shop`
FROM `ps_orders` j
LEFT JOIN `ps_order_detail` m
WHERE j.`id_customer` = 1
this is generated from original code in prestashop php on if detailed error correction is turned on -------
foreach ($result as $key)
{
$customer_id_is = 1;
$product_id_is = 5;
$result2 = Db::getInstance()->executeS(
'SELECT j.`id_customer`, j.`id_order`, m.`id_shop`
FROM `'._DB_PREFIX_.'orders` j
LEFT JOIN `'._DB_PREFIX_.'order_detail` m
WHERE j.`id_customer` = '.$customer_id_is.'
');
}
You are missing the ON clause in your JOIN
SELECT j.id_customer, j.id_order, m.id_shop FROM ps_orders j
LEFT JOIN ps_order_detail m
ON m.SomeField = j.SomeField <-- HERE
WHERE j.id_customer = 1
If you are joining your tables you need to link them on a field. Otherwise you are performing a cross join.
The MySQL Docs state:
In MySQL, JOIN, CROSS JOIN, and INNER JOIN are syntactic equivalents (they can replace each other). In standard SQL, they are not equivalent. INNER JOIN is used with an ON clause, CROSS JOIN is used otherwise.
So this would work:
SELECT j.id_customer, j.id_order, m.id_shop FROM ps_orders j
JOIN ps_order_detail m
WHERE j.id_customer = 1
as would this:
SELECT j.id_customer, j.id_order, m.id_shop FROM ps_orders j
INNER JOIN ps_order_detail m
WHERE j.id_customer = 1
But it does not work for OUTER JOINs.
When you link two tables you have to define a column on each table that connection them.
You do that in the ON condition of a JOIN which you did not specify. Example:
SELECT *
FROM table1
LEFT JOIN table2 ON table1.pk_id = table2.fk_id

Left Join After Where Clause

I'm having trouble with this query that fetches sorts forum topics on the number of replies in a different table. I tried this with Left join before the where but some data was left out in my while loop.
SELECT forum_topics.*, COUNT(forum_posts.comment_id) AS replies
FROM forum_topics
WHERE forum_topics.subcat_id = '$subcatid'
LEFT JOIN forum_posts
ON forum_topics.topic_id=forum_posts.topic_num
ORDER BY replies DESC
It gives me this as an error:
You have an error in your SQL syntax; check the manual that corresponds to your
MySQL server version for the right syntax to use near 'LEFT JOIN forum_posts ON
forum_topics.topic_id=forum_posts.topic_num ORDER BY r' at line 1
This is the query that was working before:
SELECT * FROM forum_topics WHERE subcat_id = '$subcatid' ORDER BY date DESC
To echo I use:
$getChildCategory = mysql_query($query) or die(mysql_error());
$num = mysql_num_rows($get);
if($num == 0){ echo 'No Posts';}
else{
while ($row = mysql_fetch_assoc($get)){
When echoing I only get 1 result with the left join but with the old one I got 2 which is what I expected.
That's because the clauses are in the wrong order.
This is the correct syntax (EDITED per comments below):
SELECT `forum_topics`.*, COUNT(`forum_posts`.`comment_id`) AS `replies`
FROM `forum_topics`
LEFT JOIN `forum_posts`
ON `forum_topics`.`topic_id` = `forum_posts`.`topic_num`
WHERE `forum_topics`.`subcat_id` = '$subcatid'
GROUP BY `forum_posts`.`topic_num`
ORDER BY `replies` DESC
When you perform any sort of JOIN, you create a sort of "virtual table" that is an amalgamation of all tables involved. The where clause operates on this "virtual table", so if you think about it it only makes sense for the WHERE clause to go after this table has been created.

Inner Join using COUNT(*)

I am selecting the user's information from my MySQL database as shown below:
SELECT * FROM `Users` WHERE `$user_or_id` = ?
However, I would like to add an extra bit off information to the returned data. The extra bit of data is the total number of records in a table named 'Venues' where the rows' field, 'user_id' is the same as the 'id' field in the table, 'Users'.
Please can you tell me where I am going wrong with the following query? Here is the error I am receiving:
You have an error in your SQL syntax; check the manual that
corresponds to your MySQL server version for the right syntax to use
near '*) FROM Users AS u INNER JOIN Venues AS v ON u.id =
v.user_id WHERE u.id = '' at line 1
SELECT u.*, v.count(*) FROM `Users` AS u INNER JOIN `Venues` AS v ON u.id = v.user_id WHERE u.$user_or_id = ?
SELECT u.*, COUNT(v.*) FROM `Users` AS u INNER JOIN `Venues` AS v ON u.id = v.user_id WHERE u.$user_or_id = ?
COUNT is a MySQL function, not a member of table v. Pass it an argument representing what you want to count-- in this case, v's rows.
It should be COUNT(v.*). Otherwise it's interpreted as "function count inside table V", which isn't valid.
Just use count(*) instead of v.count(*).

Categories