I'm using MariaDB 5.5, but for this solution it would be same as for MySQL. I have two tables, first one contains galleries and second one contains info about files within each gallery. This is example of the table gallery:
+----+-------+-----+
| id | name | ... |
+----+-------+-----+
| 1 | test1 | ... |
| 2 | test2 | ... |
| 3 | test3 | ... |
| 4 | test4 | ... |
+----+-------+-----+
This is example of the table gallery_items:
+----+------+------------+-----+
| id | file | gallery_id | ... |
+----+------+------------+-----+
| 1 | img1 | 3 | ... |
| 2 | img2 | 2 | ... |
| 3 | img3 | 2 | ... |
| 4 | img4 | 1 | ... |
+----+------+------------+-----+
So I tried this code:
SELECT gallery.*, COUNT(gallery_items.id) AS items FROM gallery JOIN gallery_items WHERE gallery_items.gallery_id = gallery.id;
Well, I'm not really good with databases, so this is why I'm asking for help. This is my expected result:
+----+-------+-------+-----+
| id | name | items | ... |
+----+-------+-------+-----+
| 1 | test1 | 1 | ... |
| 2 | test2 | 2 | ... |
| 3 | test3 | 1 | ... |
| 4 | test4 | 0 | ... |
+----+-------+-------+-----+
you will need to GROUP BY in order for a COUNT to work
SELECT gallery.*, COUNT(gallery_items.id) AS items FROM gallery
LEFT JOIN gallery_items ON gallery_items.gallery_id = gallery.id
GROUP BY gallery.id, gallery.name
Description You may use the following query
SELECT
g.*,COUNT(gi.id) AS items
FROM
gallery g
LEFT JOIN gallery_items gi
ON g.id = gi.gallery_id
GROUP BY g.id;
Related
this is my first time posting here. I don't seem to find the answer to my problem.
So... I'm arranging a DB for a school project, a cookbook that only shows recipes that can be made with existing elements from the "shelf".
These ingredients have to have an exact ingredients match.
user:
+---------------+------+----------+----------+
| email | name | lastname | password |
+---------------+------+----------+----------+
| pal#mail.com | John | Potato | password |
| they#mail.com | Mary | Carrot | password |
+---------------+------+----------+----------+
shelf:
+---------+------------+---------------+
| shelfID | ingredient | user |
+---------+------------+---------------+
| 1 | 1 | pal#mail.com |
| 2 | 2 | pal#mail.com |
| 3 | 3 | pal#mail.com |
| 4 | 4 | pal#mail.com |
| 5 | 10 | they#mail.com |
| 6 | 12 | they#mail.com |
+---------+------------+---------------+
This is my recipe_ingredient relationship table
recipe_ingredient:
+--------+------------+
| recipe | ingredient |
+--------+------------+
| 1 | 1 |
| 1 | 2 |
| 1 | 4 |
| 1 | 10 |
| 2 | 1 |
| 2 | 2 |
| 2 | 3 |
| 2 | 4 |
| 3 | 2 |
| 3 | 3 |
| 3 | 15 |
+--------+------------+
I've tried this query:
SELECT
rec_ing.recipe, shf.ingredient, shf.user
FROM
recipes_ingredients AS rec_ing
INNER JOIN
shelf AS shf ON rec_ing.ingredient = shf.ingredient
INNER JOIN
users AS usr ON shf.user = usr.email
WHERE
usr.email = 'pal#mail.com'
that returns this table:
+--------+------------+--------------+
| recipe | ingredient | user |
+--------+------------+--------------+
| 1 | 1 | pal#mail.com |
| 1 | 2 | pal#mail.com |
| 1 | 4 | pal#mail.com |
| 2 | 1 | pal#mail.com |
| 2 | 2 | pal#mail.com |
| 2 | 3 | pal#mail.com |
| 2 | 4 | pal#mail.com |
| 3 | 2 | pal#mail.com |
| 3 | 3 | pal#mail.com |
+--------+------------+--------------+
Although it's true that the Recipe 1 contains ingredients from my shelf, it's also missing Ingredient 10
+--------+------------+
| recipe | ingredient |
+--------+------------+
| 1 | 1 |
| 1 | 2 |
| 1 | 4 |
| 1 | 10 |
| ... | ... |
+--------+------------+
I'm trying to only get this kind of result set.
+--------+------------+
| recipe | ingredient |
+--------+------------+
| 2 | 1 |
| 2 | 2 |
| 2 | 3 |
| 2 | 4 |
+--------+------------+
Because Recipe 2 contains all elements from my shelf
I have been going around all day with this problem ... What could be missing?
This is a bit tricky, because you need to aggregate your current query by recipe, but you also need the original query to get back the full records. Sadly, MySQL does not support common table exprrssions or other features which could give us a less verbose query.
SELECT
rec_ing.recipe,
shf.ingredient,
shf.user
FROM recipes_ingredients AS rec_ing
INNER JOIN shelf AS shf
ON rec_ing.ingredient = shf.ingredient
INNER JOIN users AS usr
ON shf.user = usr.email
INNER JOIN
(
SELECT rec_ing.recipe
FROM recipes_ingredients AS rec_ing
INNER JOIN shelf AS shf
ON rec_ing.ingredient = shf.ingredient
LEFT JOIN users AS usr
ON shf.user = usr.email
WHERE
usr.email = 'pal#mail.com'
GROUP BY rec_ing.recipe
HAVING COUNT(usr.email) = COUNT(*)
) t
ON rec_ing.recipe = t.recipe
WHERE
usr.email = 'pal#mail.com'
The basic strategy here is to just do one additional join to a subquery which identifies all recipes where every ingredient belongs to a given user. The critical part is the following:
HAVING COUNT(usr.email) = COUNT(*)
This checks that the total number of rows for a given recipe matches the number of rows which have been assigned to a given user.
Here is my query and it's not showing the 3rd row even though the tables contents match.
SELECT shopcategory_idcategory_name
FROM shopcategory
INNER JOIN category ON shopcategory_id=category_id;
Result:
================================================================
| shopcategory_id | shopcategory_shopid | category_name |
================================================================
| 1 | 1 | Gadgets |
| 2 | 2 | Analog Device |
================================================================
Here is my query that shows it has 3 rows
SELECT * FROM shopcategory;
Result:
===================================================================
| shopcategory_id | shopcategory_shopid | shopcategory_categoryid |
===================================================================
| 1 | 1 | 1 |
| 2 | 2 | 2 |
| 3 | 3 | 3 |
===================================================================
EDIT: Query for my category table
SELECT * category;
Result:
==============================================
| category_id | category_name |
==============================================
| 1 | Gadgets |
| 2 | Analog Device |
| 3 | Beauty |
| 4 | Keyboard |
| 5 | Instruments |
| 6 | Monitor |
| 7 | Chairs |
==============================================
You should use LEFT JOIN here instead and add aliases for tables that you are joining on, like this:
SELECT
tableName1.shopcategory_id,
tableName1.category_name,
tableName2.category_id
FROM
tableName1 as tb1
LEFT JOIN
tableName2 AS tb2
ON
tb1.shopcategory_id = tb2.category_id
GROUP BY
tb1.shopcategory_id;
I have two tables that look like this:
Table A:
+-----+-----+------+-------+
| aID | uID | attr | value |
+-----+-----+------+-------+
| 1 | 1 | fn | john |
+-----+-----+------+-------+
| 2 | 1 | ln | smith |
+-----+-----+------+-------+
| 3 | 2 | fn | jim |
+-----+-----+------+-------+
| 4 | 2 | ln | bean |
+-----+-----+------+-------+
Table B:
+-----+-----+-------+-------+
| bID | uID | perm | value |
+-----+-----+-------+-------+
| 1 | 1 | admin | 1 |
+-----+-----+-------+-------+
| 2 | 2 | news | 1 |
+-----+-----+-------+-------+
| 3 | 2 | cms | 1 |
+-----+-----+-------+-------+
As it shows, Table A holds attribute data for a user uID, and Table B holds permission data for a user uID.
At the moment, I am using,:
SELECT GROUP_CONCAT(`a`.`attr`) AS `attrs`
, GROUP_CONCAT(`a`.`value`) AS `values`
, GROUP_CONCAT(`b`.`perm`) AS `perms`
FROM `a`
JOIN `b`
ON `a`.`uID` = `b`.`uID`
GROUP BY `a`.`uID`, `b`.`uID`
But it is giving me a result:
+-------------+-------------------+-------------------+
| attrs | values | perms |
+-------------+-------------------+-------------------+
| fn,ln | John,Smith | admin,admin |
+-------------+-------------------+-------------------+
| fn,fn,ln,ln | Jim,Jim,Bean,Bean | news,cms,news,cms |
+-------------+-------------------+-------------------+
What do I need to change in my query to get:
+-------+------------+----------+
| attrs | values | perms |
+-------+------------+----------+
| fn,ln | John,Smith | admin |
+-------+------------+----------+
| fn,fn | Jim,Bean | news,cms |
+-------+------------+----------+
GROUP_CONCAT takes additional arguments, as explained on its documentation page here.
The one you want is distinct:
SELECT GROUP_CONCAT(distinct `a`.`attr`) AS `attrs` . . .
So I'm not all to great at complex MySQL statements so I'm hoping you guys can help me out.
Say I have four tables, MainTable, AttrTable, NameTable, and ValueTable.
MainTable looks like this:
| id | title | category |
.........................
| 1 | First | Cat1 |
.........................
| 2 | Second| Cat2 |
.........................
| 3 | Third | Cat3 |
AttrTable looks like this:
| id | mainId | nameId | valueId |
..................................
| 1 | 1 | 1 | 2 |
..................................
| 2 | 1 | 2 | 1 |
..................................
| 3 | 2 | 1 | 3 |
..................................
| 4 | 3 | 3 | 2 |
..................................
| 1 | 3 | 1 | 1 |
NameTable and ValueTable each looks like this:
| id | title | | id | title |
.............. ..............
| 1 | foo | | 1 | bar |
.............. ..............
| 2 | john | | 2 | smith |
.............. ..............
| 3 | dink | | 3 | fink |
So I want to write a statement that combines all the data associated with each row of the MainTable into its own row. Eg: I want a statment that would give me back something like:
| 1 | First | Cat1 | foo | smith | john | bar |
| 2 | Second| Cat2 | foo | fink |
etc...
Is that possible? I'd even settle for something like:
| 1 | First | Cat1 | foo | smith |
| 1 | First | Cat1 | john | bar |
| 2 | Second | Cat2 | foo | fink |
etc...
Hopefully this all makes sense. Thanks in advance for any help.
Sounds like you just want this:
select m.id,
m.title,
m.category,
n.title,
v.title
from maintable m
left join attrtable a
on m.id = a.mainid
left join nametable n
on a.nameid = n.id
left join valuetable v
on a.valueid = v.id
see SQL Fiddle with Demo
Query not checked! (and may need to be tweaked)
select m.*, n.title, v.title from MainTable m
join AttrTable a on a.mainId = m.id
join NameTable n on n.id = a.nameId
join ValueTable v on v.id = a.valueId
I have two tables like below,
mysql> select * from Books ;
+----+------+------------+----------+----------+
| id | name | author_name| category | category2|
+----+------+------------+----------+----------+
| 1 | 1 | Steve | CT001 | CT003 |
| 2 | 2 | John | CT002 | CT002 |
| 3 | 3 | Larry | CT003 | CT002 |
| 4 | 3 | Michael | CT004 | CT004 |
| 5 | NULL | Steven | CT005 | CT005 |
+----+------+------------+----------+----------+
mysql> select * from Codemst ;
+----+------+------------+
| id | code | name |
+----+------+------------+
| 1 | CT001| fiction |
| 2 | CT002| category1 |
| 3 | CT003| etc |
| 4 | CT004| etc2 |
| 5 | CT005| etc3 |
+----+------+------------+
I want to get human readable category name when I query like "select * from Books;"
If there was only one category in the Books table, I think I can use "Join" but, in this case what can I do?
select * from Books b
Inner Join Codemst c1 on b.category = c1.code
inner join codemst c2 on b.category2 = c2.code;
c1.name will hold the readable category, and c2.name the readable category2