I tried to combine two tables' data.
I got an error like this. can you see why?
Every derived table must have its own alias
SELECT a.title, number
FROM store a
JOIN
( SELECT count(b.code) as number
FROM redeem_codes b
WHERE product = a.title
AND available = "Available")
It's a little hard tell without knowing more about your table structures. I'll give a try anyway:
SELECT a.title, count(b.code) AS number FROM store a
LEFT JOIN redeem_codes b ON b.product = a.title
WHERE b.available = "Available"
GROUP BY a.title;
you need to have ALIAS on your subquery.
SELECT a.title, number
FROM store a
JOIN (subquery) b -- b is the `ALIAS`
-- and this query will not give you the result you want
but here's a more efficient query without using subquery,
SELECT a.title, count(b.code) number
FROM store a
INNER JOIN redeem_codes b -- or use LEFT JOIN to show 0
-- for those who have no product
ON b.product = a.title
WHERE b.available = 'Available'
GROUP BY a.title
Related
I am new to MySQL I have one query which works perfectly fine with inner join but with inner join some records got missing I want all the data from both the table but when i use full outer join or full join it gives error unknown column classroom.id in field list
here is the query
SELECT
classroom.id as id,
classroom.grade as grade,
classroom.status as status,
teacher.id as tid,
teacher.name as tname
FROM classroom
FULL JOIN teacher on classroom.teacherId = teacher.id
ORDER BY grade ASC
these are my two tables you can see in the picture enter image description here
and also I mention in column
classroom
id,grade,teacherid,status
teacher
id,email,password,name,status,role
MySQL does not support a FULL OUTER JOIN or FULL JOIN, you have to emulate it using UNION with LEFT JOIN and RIGHT JOIN.
Read more about it here: Why does MySQL report a syntax error on FULL OUTER JOIN?
So your syntax should look like this:
SELECT * FROM
(SELECT
a.id as id,
a.grade as grade,
a.status as status,
b.id as tid,
b.name as tname
FROM classroom a
LEFT JOIN teacher b ON a.teacherId = b.id
UNION
SELECT
a.id as id,
a.grade as grade,
a.status as status,
b.id as tid,
b.name as tname
FROM classroom a
RIGHT JOIN teacher b ON a.teacherId = b.id) c
WHERE c.grade != '' AND c.grade IS NOT NULL
ORDER BY c.grade ASC
UPDATE: Per your comments below, I've include a WHERE clause to remove NULL values AND empty '' values. You could also write a WHERE clause in each of the UNION queries above but I find it easier to put it in a subquery and write the WHERE clause once in the outer query. I've also added aliases a, b, c so its easier to read vs. using the table names.
Demo here.
I have two tables, like so:
table "a" contains:
id|name
stock1|fullname
stock2|fullname2
stock3|fullname3
table "b" contains product quantities for given stock.
id|stock_id|quantity|product_id|
1|stock1|3|13
2|stock3|4|13
3|stock1|1|5
4|stock2|2|2
Now I would need to combine those two tables, so that each product takes its stock full name from table "a", and if its quanitity is not given for stock, it would still show the row with the quanitity as 0.
So from my example, product_id 13 would show as:
stock|quanitity|product_id|stock_fullname
stock1|3|13|fullname1
stock2|0|13|fullname2
stock3|4|13|fullname3
You should be able to use a LEFT JOIN to achieve this.
SELECT a.id AS stock, COALESCE(b.quanitity,0), b.product_id, a.name AS stock_fullname
FROM a
LEFT JOIN b
ON a.id = b.stock_id
AND b.product_id = 13
It sounds like you need to use a LEFT JOIN, although the records with no quantity might show as NULL rather than zero. Something like:
SELECT a.*, b.*
FROM table_a a
LEFT JOIN table_b b ON a.stock_id = b.stock_id
try this:
SELECT stock,COALESCE(quanitity,0),product_id,stock_fullname FROM stock JOIN product
You need an outer join so that rows from the a table without a corresponding row in b are still considered. An inner join, by contrast, insists that you have a matching row. If you are pulling a value from the table where you don't have a row, you get NULL. Syntax varies between DBs and there is a distinction made depending on if it's the table on the left or right that gets the fake rows.
see other answers for syntax.
I think this query should work for your example:
SELECT a.id stock if(b.quantity IS NULL, 0, b.quantity),
b.product_id, a.name stock_fullname
FROM b
LEFT JOIN a b.stock = a.id
WHERE b.product_id = 13;
You should be able to use a LEFT JOIN to achieve this.
SELECT a.id AS stock, COALESCE(b.quanitity,0), b.product_id, a.name AS stock_fullname
FROM a
LEFT JOIN b
ON a.id = b.stock_id
AND b.product_id = 13
I am combining three tables - persons, properties, totals - using LEFT JOIN. I find the following query to be really fast but it does not give me all rows from table-1 for which there is no corresponding data in table-2 or table-3. Basically, it gives me only rows where there is data in table-2 and table-3.
SELECT a.*, b.propery_address, c.person_asset_total
FROM persons AS a
LEFT JOIN properties AS b ON a.id = b.person_id
LEFT JOIN totals AS c ON a.id = c.person_id
WHERE a.city = 'New York' AND
c.description = 'Total Immovable'
Whereas the following query gives me the correct result by including all rows from table-1 irrespective of whether there is corresponding data or no data from table-2 and table-3. However, this query is taking a really long processing time.
FROM persons AS a
LEFT JOIN
properties AS b ON a.id = b.person_id
LEFT JOIN
(SELECT person_id, person_asset_total
FROM totals
WHERE description = 'Total Immovable'
) AS c ON a.id = c.person_id
WHERE a.city = 'New York'
Is there a better way to write a query that will give data equivalent to second query but with speed of execution equivalent to the first query?
Don't use a subquery:
SELECT p.*, pr.propery_address, t.person_asset_total
FROM persons p LEFT JOIN
properties pr
ON p.id = pr.person_id LEFT JOIN
totals t
ON a.id = c.person_id AND t.description = 'Total Immovable'
WHERE p.city = 'New York';
Your approach would be fine in almost any other database. However, MySQL materializes "derived tables", which makes them much harder to optimize. The above has the same effect.
You will also notice that I changed the table aliases to be abbreviations for the table names. This makes the query much easier to follow.
I have 3 tables each have almost 70,000 data
when i execute select query in which i add one inner join than it works faster.
Following works faster
select A.id from product as A
inner join product_cat as B on A.id=B.mapped_id
OR
select A.id from product as A
inner join product_sup as C on A.id = C.mapped_id
(It works faster for one inner join)
but when i add both inner join in same select query than it works too slower(Does not display data it just show loading label in phpmyadmin)
select A.id
from product as A
inner join product_cat as B
on A.id = B.mapped_id
inner join product_sup as C
on A.id = C.mapped_id
my purpose it only to find out how much record is there in database.
also tried with count function though takes too much time.
Any help will be appreciated,
Thanks,
Use EXPLAIN to analyze performance of the query and identify any missing indexes.
http://dev.mysql.com/doc/refman/5.5/en/using-explain.html
http://dev.mysql.com/doc/refman/5.5/en/explain-output.html
Add your actual query, execution plan printed by EXPLAIN and CREATE TABLE statements of all involved tables to your question if you want to get a specific advice.
Maybe your query is trying to return more than 1 million of result and that is the reason fo the slowness. Maybe you are doing a Cartesian product between tables B and C.
Let's put an example.
Table (A) = (id=1)
Table (B) = (id=1,mapped_id=1),(id=2,mapped_id=1),
(id=3,mapped_id=1),(id=4,mapped_id=1)
Table (C) = (id=1,mapped_id=1),(id=2,mapped_id=1), (id=3,mapped_id=1)
If we do that query with those data it would return 12 rows, all of them with A.id=1
To solve the problem you could try to use a DISTINCT on the SELECT clause or to do a group with the GROUP BYclase, but I think the better solution is to redesing the query depending on your goals.
If you want to use the group by your query will be something like this
select A.id from product as A
inner join product_cat as B on A.id = B.mapped_id
inner join product_sup as C on A.id = C.mapped_id
group by A.id
I have two tables, like so:
table "a" contains:
id|name
stock1|fullname
stock2|fullname2
stock3|fullname3
table "b" contains product quantities for given stock.
id|stock_id|quantity|product_id|
1|stock1|3|13
2|stock3|4|13
3|stock1|1|5
4|stock2|2|2
Now I would need to combine those two tables, so that each product takes its stock full name from table "a", and if its quanitity is not given for stock, it would still show the row with the quanitity as 0.
So from my example, product_id 13 would show as:
stock|quanitity|product_id|stock_fullname
stock1|3|13|fullname1
stock2|0|13|fullname2
stock3|4|13|fullname3
You should be able to use a LEFT JOIN to achieve this.
SELECT a.id AS stock, COALESCE(b.quanitity,0), b.product_id, a.name AS stock_fullname
FROM a
LEFT JOIN b
ON a.id = b.stock_id
AND b.product_id = 13
It sounds like you need to use a LEFT JOIN, although the records with no quantity might show as NULL rather than zero. Something like:
SELECT a.*, b.*
FROM table_a a
LEFT JOIN table_b b ON a.stock_id = b.stock_id
try this:
SELECT stock,COALESCE(quanitity,0),product_id,stock_fullname FROM stock JOIN product
You need an outer join so that rows from the a table without a corresponding row in b are still considered. An inner join, by contrast, insists that you have a matching row. If you are pulling a value from the table where you don't have a row, you get NULL. Syntax varies between DBs and there is a distinction made depending on if it's the table on the left or right that gets the fake rows.
see other answers for syntax.
I think this query should work for your example:
SELECT a.id stock if(b.quantity IS NULL, 0, b.quantity),
b.product_id, a.name stock_fullname
FROM b
LEFT JOIN a b.stock = a.id
WHERE b.product_id = 13;
You should be able to use a LEFT JOIN to achieve this.
SELECT a.id AS stock, COALESCE(b.quanitity,0), b.product_id, a.name AS stock_fullname
FROM a
LEFT JOIN b
ON a.id = b.stock_id
AND b.product_id = 13