MySQL query multiple table inner join [duplicate] - mysql

This question already has an answer here:
Syntax error due to using a reserved word as a table or column name in MySQL
(1 answer)
Closed 8 years ago.
I have this MySQL query but it seems to be getting an error while I try to run it. Since I'm a newbie I'd like some advice of what I should do to correct it. I just want to show the name, quantity and order date of the orders that has 1 or more pending products. Thanks a lot!
select product.name, order_details.quantity, order.date from product,order_details,order
inner join order on order_details.order_id=order.id
inner join product on order_details.product_id=product.id
inner join customer on order.cust_id=costumer.id WHERE order.pending=>1

You have a table called order. This word has special significance in SQL. Your options are to rename the table, or quote it whenever you want to query from it.
Easiest solution is to change.
inner join order ....
to
inner join `order`
Be sure to use back-quotes around the table name.

You have a table named 'order', which is a reserved word in SQL.
One solution is to prefix the table name with the database name as explained in Craic Computing blog
Another one is to wrap the table name with the ` character as you can read in this StackOverflow question

You can try something like :
SELECT product.name, order_details.quantity, `order`.date
FROM product
INNER JOIN order_details ON product.id = order_detail.product_id
INNER JOIN `order` ON `order`.id = order_detail.order_id
WHERE `order`.pending >= 1
As said in other answers, orderis a reserved keyword in SQL, surround it with backquotes.
Maybe you should store the pending information in the order_detail table (1 if pending, 0 if not), in order to keep track of which product is still pending instead of incrementing/decrementing the order.pending field.
In this case, you could make the following query :
SELECT product.name, order_details.quantity, `order`.date
FROM product
INNER JOIN order_details ON product.id = order_detail.product_id
INNER JOIN `order` ON `order`.id = order_detail.order_id
WHERE `order_detail`.pending = 1
Which would return all the products still pending in your orders instead of every product from orders in which maybe only one is pending.

Related

mysql checking if product ID also exist in other table [duplicate]

This question already has answers here:
Select rows which are not present in other table
(4 answers)
Closed 2 years ago.
I have not much experience with JOINS and the result I get with query below isn't correct.
I have a table called products and want to check if there are records in the table product_links.
I only want to get a list of items that doesn't have rows in product_links.
When I run the below query, I only get one line.
Anybody suggestions? Google couldn't help me or I'm searching with the wrong keywords.
SELECT a.id, a.SKU, a.title,
(SELECT COUNT(b.id) AS amount FROM product_links WHERE b.product=a.id) AS amount
FROM products AS a
LEFT JOIN product_links AS b ON b.product=a.id
I would recommend not exists:
select p.*
from products p
where not exists (select 1 from product_links pl where pl.product_id = p.id)
From your question i understand you need info of products which doesnt have any links.
Below is the query for that
SELECT * FROM products
WHERE id NOT IN (SELECT id FROM product_links);

SQL Inner Join 2 Tables

Hoping to get some help with this, I have made a few attempts at an inner join that shows all 'Product' information from the product table for, any product that has sold more than 10 units using an inner join.
PRODUCT TABLE (Columns)
P_CODE, P_DESCRIPT, P_INDATE, P_QOH, P_MIN, P_PRICE, P_DISCOUNT, V_CODE
LINE TABLE (Columns) this table shows the lines/information for each
invoice
INV_NUMBER, LINE NUMBER, P_CODE, LINE_UNITS, LINE_PRICE, LINE_TOTAL
I understand that I have to make the join using the common key attribute (p_code) but I cannot figure out how to do the sum within the inner join.
Here is my most recent attempt:
SELECT * PRODUCT FROM PRODUCT
INNER JOIN line
ON product.p_code = line.p_code
WHERE sum(line_units) >=10
AND line.p_code = product.p_code;
Error: near "product"; syntax error
Any help would be appreciated,
Thank you.
Looks like you have the table name PRODUCT within the SELECT section. And the sum() needs to happen within the SELECT section along with the extra HAVING clause at the end.
SELECT *, sum(line_units) as line_units_sum FROM product
INNER JOIN line ON product.p_code = line.p_code
WHERE line.p_code = product.p_code
HAVING line_units_sum >= 10
The requirement
Show all product information from the product table for any product that has sold more than 10 units.
The solution
Because you only want to build the projection from the product table, and you don't need any column from the line table, you can also use a correlated subquery like the following one:
SELECT *
FROM product
WHERE 10 < (
SELECT COUNT(*)
FROM line
WHERE line.p_code = product.p_code
)
The database optimizer might choose to use a JOIN internally if the cost of the JOIN is lower than other alternatives. So, it does not mean that the query will do row-by-row processing for the outer table records. Only the execution plan can tell how the query is executed by the database engine.

SQL Query to Filter a Table using two tables

I currently have 4 SQL tables that look like this:
CustomersTable, RegistrationTable, OrdersTable and OffersTable
enter image description here
I need to write a SELECT statement that retrieves all customers from the CustomersTable (all the fields) that contain rows that match the RegistrationTable Or rows that match the OrdersTable with status "closed", in the result table shouldn't display duplicate customers.
As you realized, CustomersTable and RegistrationTable have the field in common "customerId", but between CustomersTable and OrdersTable there is no field in common. However there is another table (OffersTable) which has the fields "customerId" and "ID", to query information to Customers and Orders table respectively. Remember that a customer who appears in OfferTable not necessarily will appear in OrderTable or just the status is NOT "Closed"
So based on my example tables above, if I were to run the query, it would return the following result:
enter image description here
In the result table shouldn't display duplicate customers.
I really appreciate your help.
Thanks for your time !!
Note - I am using MySQL
Try Using "Union" and "inner join" with every table Like below:
Select Customers.* from Customers inner join Registration on Customers. customerId= Registration.customerId
union
Select Customers.* from Customers inner join offers on Customers.customerId=offers.customerId
inner join Orders on orders.Id= offers.Id and Orders.Status='closed'
I would think exists or in, given what you want. Your description of the table is a bit cumbersome -- which is why sample data in the question is so helpful.
The resulting query would look something like this:
select c.*
from customers c
where exists (select 1 from registrations r where r.customerid = c.customerid) or
exists (select 1
from offers o join
orders oo
on o.id = oo.orderid
where o.customerid = c.customerid and
oo.status = 'closed'
);
The column names may not be quite right.

MySQL - How to JOIN with an unexisting index?

I have a table in my DB called ORDERS and it looks like this:
ID_section (int), ID_price (int), ID_city (int), ID_company (int)
And I want to use the JOIN method to set names to the ID's.
What I would do is:
SELECT * FROM ORDERS
JOIN sections ON sections.id=orders.ID_section
JOIN prices ON prices.id=orders.ID_price
JOIN cities on cities.id=orders.ID_cities
JOIN companies ON companies.id=orders.ID_company
But the point is, that in ORDERS table can be inserted value of 0 and it means - all the sections/prices/cities/companies, but when I run my query, only the values, that their ID exist in the other table show up.
Any ideas? Thanks.
If I understand you question correctly and having, for example, ID_section = 0 means that the order belongs to all the section then the following query should do the trick.
SELECT * FROM ORDERS
JOIN sections ON sections.id=orders.ID_section OR orders.ID_section = 0
JOIN prices ON prices.id=orders.ID_price OR orders.ID_price = 0
JOIN cities on cities.id=orders.ID_cities OR orders.ID_cities = 0
JOIN companies ON companies.id=orders.ID_company OR orders.ID_company = 0
If, on the other hand, you want to retrieve all orders regardless if they have sections, prices, etc. associated, then it is sufficient to put LEFT JOIN where you have JOIN. (But this situation does not result from your question! I only added it because people seem to understand that.)
Use LEFT JOIN instead of JOIN (which is a shorthand for INNER JOIN)
Experiment with LEFT and RIGHT OUTER JOIN s and you'll be able to figure out what you need to do. Basically a LEFT or RIGHT OUTER JOIN will insert NULLS into columns where no data exists but still do the joins.
There are various resources on the web that explain this.

Problem joining on the highest value in mysql table

I have a products table...
alt text http://img357.imageshack.us/img357/6393/productscx5.gif
and a revisions table, which is supposed to track changes to product info
alt text http://img124.imageshack.us/img124/1139/revisionslz5.gif
I try to query the database for all products, with their most recent revision...
select
*
from `products` as `p`
left join `revisions` as `r` on `r`.`product_id` = `p`.`product_id`
group by `p`.`product_id`
order by `r`.`modified` desc
but I always just get the first revision. I need to do this in one select (ie no sub queries). I can manage it in mssql, is this even possible in mysql?
Here's how I'd do it:
SELECT p.*, r.*
FROM products AS p
JOIN revisions AS r USING (product_id)
LEFT OUTER JOIN revisions AS r2
ON (r.product_id = r2.product_id AND r.modified < r2.modified)
WHERE r2.revision_id IS NULL;
In other words: find the revision for which no other revision exists with the same product_id and a greater modified value.
Begin and end dates on your history table would make this possible.(leaving the most recent end date null and stamping end dates on the previous record as you insert a new one)
Otherwise you will have to use a sub-query.
That same query is parsable in MySQL.
Why are you using a Left JOIN instead of an INNER join or a RIGHT join?
Also if you want to go about this in a different way, you have the MAX function at your disposal.