简体   繁体   中英

mysql count and join 4 tables

I have the following table structure:

Table folder
id | title | is_hidden

Table object
id | name | is_hidden | folder_id

Table label
id | name

Table label_to_folder
id | label_id | folder_id

  • Each object always belongs to a folder.
  • Each folder may belong to one or more labels (this is defined by the label_to_folder table)

I'm trying to get the most used (popular) labels, and I achieve it (I think :P) with the following query: SELECT COUNT(lf.label_id) AS cnt, lf.label_id, l.name FROM label_to_folder lf JOIN label l ON lf.label_id=l.id GROUP BY lf.label_id ORDER BY cnt DESC limit 8

What I'm having trouble with, is extent the above query so it does not count hidden folders (folder.is_hidden=1) or empty folders (an empty folder is one with no objects at all or all the folder's objects are hidden)

Any help appreciated.

EDIT

sqlfiddle: http://sqlfiddle.com/#!9/65526/1 The result there includes folder with id 5, but all its folders are empty - that's what I'm trying to eliminate.

You get used folders thus:

select f.id
from folder f
where f.is_hidden = 0
and exists 
(
  select * 
  from object o
  where o.folder_id = f.id
  and o.is_hidden = 0
)

Then you can add this to your query:

where lf.folder_id in (<above subquery>)

Assuming the following produces the desired intermediate result, then the subsequent query provides a count of same...

SELECT l.id label_id
     , l.name label_name
     , f.id folder_id
     , f.title folder_title
     , f.is_hidden folder_is_hidden
     , o.id object_id
     , o.name object_name
     , o.is_hidden object_is_hidden
  FROM label l
  JOIN label_to_folder lf
    ON lf.label_id = l.id
  JOIN folder f
    ON f.id = lf.folder_id
  JOIN object o
    ON o.folder_id = f.id
 WHERE f.is_hidden = 0
   AND o.is_hidden = 0
 ORDER
    BY label_id;
+----------+------------+-----------+--------------+------------------+-----------+-------------+------------------+
| label_id | label_name | folder_id | folder_title | folder_is_hidden | object_id | object_name | object_is_hidden |
+----------+------------+-----------+--------------+------------------+-----------+-------------+------------------+
|        4 | l3         |         4 | Folder 3     |                0 |         6 | object F    |                0 |
|        4 | l3         |         6 | Folder 5     |                0 |         7 | object G    |                0 |
|        4 | l3         |        10 | Folder 9     |                0 |        10 | object J    |                0 |
|        4 | l3         |         6 | Folder 5     |                0 |         9 | object I    |                0 |
|        4 | l3         |        11 | Folder 10    |                0 |        11 | object K    |                0 |
|        4 | l3         |         4 | Folder 3     |                0 |         1 | object A    |                0 |
|        4 | l3         |         4 | Folder 3     |                0 |         2 | object B    |                0 |
|        4 | l3         |         4 | Folder 3     |                0 |         3 | object C    |                0 |
|        4 | l3         |         6 | Folder 5     |                0 |         8 | object H    |                0 |
|        4 | l3         |         4 | Folder 3     |                0 |         4 | object D    |                0 |
|        4 | l3         |         4 | Folder 3     |                0 |         5 | object E    |                0 |
|        6 | l5         |         6 | Folder 5     |                0 |         8 | object H    |                0 |
|        6 | l5         |         4 | Folder 3     |                0 |         1 | object A    |                0 |
|        6 | l5         |         4 | Folder 3     |                0 |         2 | object B    |                0 |
|        6 | l5         |         6 | Folder 5     |                0 |         7 | object G    |                0 |
|        6 | l5         |         4 | Folder 3     |                0 |         3 | object C    |                0 |
|        6 | l5         |         4 | Folder 3     |                0 |         4 | object D    |                0 |
|        6 | l5         |         4 | Folder 3     |                0 |         5 | object E    |                0 |
|        6 | l5         |         4 | Folder 3     |                0 |         6 | object F    |                0 |
|        6 | l5         |         6 | Folder 5     |                0 |         9 | object I    |                0 |
|        9 | l8         |         4 | Folder 3     |                0 |         2 | object B    |                0 |
|        9 | l8         |         4 | Folder 3     |                0 |         3 | object C    |                0 |
|        9 | l8         |         4 | Folder 3     |                0 |         4 | object D    |                0 |
|        9 | l8         |         4 | Folder 3     |                0 |         5 | object E    |                0 |
|        9 | l8         |         4 | Folder 3     |                0 |         6 | object F    |                0 |
|        9 | l8         |         4 | Folder 3     |                0 |         1 | object A    |                0 |
+----------+------------+-----------+--------------+------------------+-----------+-------------+------------------+

SELECT l.id label_id
     , l.name label_name
     , COUNT(*) total
  FROM label l
  JOIN label_to_folder lf
    ON lf.label_id = l.id
  JOIN folder f
    ON f.id = lf.folder_id
  JOIN object o
    ON o.folder_id = f.id
 WHERE f.is_hidden = 0
   AND o.is_hidden = 0
 GROUP
    BY l.id
 ORDER 
    BY total DESC 
 LIMIT 3;
+----------+------------+-------+
| label_id | label_name | total |
+----------+------------+-------+
|        4 | l3         |    11 |
|        6 | l5         |     9 |
|        9 | l8         |     6 |
+----------+------------+-------+

Did you try the following query?

SELECT COUNT(lf.label_id) AS cnt
     , lf.label_id
     , l.name 
  FROM label_to_folder lf 
  JOIN label l 
    ON lf.label_id = l.id 
  JOIN object o 
    ON o.folder_id = l.folder_id 
  JOIN folder f 
    ON f.id = l.folder_id 
 WHERE f.is_hidden = 1 
   AND o.is_hidden = 1 
 GROUP 
    BY lf.label_id 
 ORDER 
    BY cnt DESC 
 LIMIT 8

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM