MYSQL: Howto get last download from 2 joined tables - php

This is my first question, so please be nice :)
I have this:
mysql> select cat_id, cat_name from phpbb_dm_eds_cat;
+--------+----------+
| cat_id | cat_name |
+--------+----------+
| 9 | catx |
| 10 | cat2 |
| 11 | test |
+--------+----------+
mysql> select subcat_id, subcat_name from phpbb_dm_eds_subcat;
+-----------+--------------+
| subcat_id | subcat_name |
+-----------+--------------+
| 39 | aaa |
| 40 | xxx111 |
| 41 | TESTXX |
| 42 | xxa |
+-----------+--------------+
Here is the download table:
mysql> select download_id, download_title, download_cat_id from phpbb_dm_eds;
+-------------+----------------+-----------------+
| download_id | download_title | download_cat_id |
+-------------+----------------+-----------------+
| 3 | s | 9 |
| 5 | raver | 41 |
| 6 | hans | 10 |
| 7 | readme | 42 |
+-------------+----------------+-----------------+
Now the query:
mysql>
SELECT bc.cat_name, bc.cat_id,
COUNT(bd.download_id) AS number_downloads,
MAX(bd.last_changed_time) AS last_download
FROM phpbb_dm_eds_cat bc
LEFT JOIN phpbb_dm_eds bd ON bd.download_cat_id = bc.cat_id
GROUP BY bc.cat_id ;
+----------+--------+------------------+---------------+
| cat_name | cat_id | number_downloads | last_download |
+----------+--------+------------------+---------------+
| catx | 9 | 1 | 1427072549 |
| cat2 | 10 | 1 | 1427125950 |
| test | 11 | 0 | NULL |
+----------+--------+------------------+---------------+
the 'test' category has a subcategory which has a download in the subcat table, the categories 'catx' and 'cat2' have downloads too, there the last download is displayed correctly but i want the last_download in the subcat 'test' to be displayed too
How do I write the query?

You are not clear about what you want but it might be:
SELECT bc.cat_name, bc.cat_id,
COUNT(bd.download_id) AS number_downloads,
MAX(bd.last_changed_time) AS last_download
FROM (
select cat_id, cat_name from phpbb_dm_eds_cat
union
select subcat_id as cat_id, subcat_name as cat_name
from phpbb_dm_eds_subcat
) as bc
LEFT JOIN phpbb_dm_eds bd ON bd.download_cat_id = bc.cat_id
GROUP BY bc.cat_id ;
(Your SELECT is using a MySQL extension, because cat_id is neither in the GROUP BY nor in an aggregate.)

From your notes"the 'test' category has a subcategory" ,i suggest there should be a relation between cat table "phpbb_dm_eds_cat" and sub_cat table
"phpbb_dm_eds_subcat".
Like this:
Table name
phpbb_dm_eds_cat
Columns
(cat_id,cat_name)
Tablename
phpbb_dm_eds_subcat
Columns
(cat_id referencing table phpbb_dm_eds_cat(cat_id),subcat_id,subcat_name)

Sadly your query doesn't work, it gives me ALL subcats, like this:
+----------+--------+------------------+---------------+
| cat_name | cat_id | number_downloads | last_download |
+----------+--------+------------------+---------------+
| catx | 9 | 1 | 1427072549 |
| cat2 | 10 | 1 | 1427125950 |
| test | 11 | 0 | NULL |
| aaa | 39 | 0 | NULL |
| xxx111 | 40 | 0 | NULL |
| TESTXX | 41 | 1 | 1427123713 |
| xxa | 42 | 1 | 1427136789 |
+----------+--------+------------------+---------------+
7 rows in set (0,00 sec)
I don't want the subcats to be displayed, I only want the last download from the subcat, this should be the correct output:
+----------+--------+------------------+---------------+
| cat_name | cat_id | number_downloads | last_download |
+----------+--------+------------------+---------------+
| catx | 9 | 1 | 1427072549 |
| cat2 | 10 | 1 | 1427125950 |
| test | 11 | 1 | 1427213321 |
+----------+--------+------------------+---------------+
3 rows in set (0,00 sec)

Related

how to find displaying data where data not exist in the other table

I have 3 tables:
table_1:
| id | test |total_employee|
+----+------+--------------+
| 1 | xxxx | 3 |
| 2 | yyyy | 2 |
| 3 | zzzz | 3 |
----------------------------
table_2:
| id | id_table1 |id_employee|
+----+-----------+-----------+
| 1 | 1 | 1 |
| 2 | 1 | 2 |
| 3 | 1 | 3 |
| 4 | 1 | 1 |
| 5 | 1 | 2 |
| 6 | 1 | 1 |
| 7 | 1 | 2 |
| 8 | 1 | 3 |
-----------------------------
table employee:
| id | name |
+----+------+
| 1 | emp1 |
| 2 | emp2 |
| 3 | emp3 |
-------------
and now I want to display all employees from table employee and from table_2 if the employee record in table employee exists but in table_2 it does not. If record does not exist mark as "unchecked" but if exists mark as "checked".
The point is how to find data from table_employee no matter data is exist or not exist on table_2.
The IF() operation lets you do this:
SELECT e.*, IF(ISNULL(t2.id), 'unchecked', 'checked') AS `checked`
FROM table_employee e
LEFT JOIN table_2 t2 ON t2.id_employee = e.id

Find the ranking for Concatenated rows in mysql

I have a table with concatenated values within both rows, I am therefore uniquely retrieve ranking for each row in the tables.
UPDATE
The other tables has been added to question
NamesTable
NID | Name |
1 | Mu |
2 | Ni |
3 | ices |
GroupTable
GID | GName |
1 | GroupA |
2 | GroupB |
3 | GroupC |
MainTable
| NID | Ages | Group |
| 1 | 84 | 1 |
| 2 | 64 | 1 |
| 3 | 78 | 1 |
| 1 | 63 | 2 |
| 2 | 25 | 2 |
| 3 | 87 | 2 |
| 1 | 43 | 3 |
| 2 | 62 | 3 |
| 3 | 37 | 3 |
Now the first Name is equated to the first age in the table, I am able to equate them using php and foreach statements, Now the problem is with the ranking of the ages per each group. I am ranking the names uniquely on each row or group.
Results which is expected
| Names | Ages | Group | Ranking |
| Mu,Ni,ices | 84,64,78 | 1 | 1,3,2 |
| Mu,Ni,ices | 63,25,87 | 2 | 2,3,1 |
| Mu,Ni,ices | 43,62,37 | 3 | 2,1,3 |
In my quest to solving this, I am using GROUP_CONCAT, and I have been able to come to this level in the below query
SELECT
GROUP_CONCAT(Names) NAMES,
GROUP_CONCAT(Ages) AGES,
GROUP_CONCAT(Group) GROUPS,
GROUP_CONCAT( FIND_IN_SET(Ages, (
SELECT
GROUP_CONCAT( Age ORDER BY Age DESC)
FROM (
SELECT
GROUP_CONCAT(Ages ORDER BY Ages DESC ) Age
FROM
`MainTable` s
GROUP by `Group`
) s
)
)) rank
FROM
`MainTable` c
GROUP by `Group`
This actually gives me the below results.
| Names | Ages | Group | Ranking |
| 1,2,3 | 84,64,78 | 1 | 7,9,8 |
| 1,2,3 | 63,25,87 | 2 | 5,6,4 |
| 1,2,3 | 43,62,37 | 3 | 2,1,3 |
The only problem is that the ranking Values increase from 1 to 9 instead of ranking each row uniquely. Its there any idea that can help me cross over and fix this? I would be grateful for your help. Thanks

MySQL get Related and Unrelated Records from Table in One Query

I have a user and pages table, and these two have many to many relationship between them with the bridge table user privileges. What I want to get all the pages name and only those are marked that is assigned to that user.
want some think like this
+---------+----------------------------------+
| user_id | page_name | Assigned|
+---------+----------------------------------+
| 1 | Add Project | 0 |
| 1 | Department | 0 |
| 1 | Category | 1 |
| 1 | Item | 0 |
| 1 | Units | 1 |
| 1 | Stock In | 0 |
| 1 | Stock Card Report | 1 |
+---------+------------------------+---------|
for now my query is this;
Select up.user_id, p.page_name FROM user_privileges up, pages p where p.page_id = up.page_id and up.user_id = 1;
and it returns this;
+---------+------------------------+
| user_id | page_name |
+---------+------------------------+
| 1 | Add Project |
| 1 | Department |
| 1 | Category |
| 1 | Item |
| 1 | Units |
| 1 | Stock In |
| 1 | Stock Card Report |
+---------+------------------------+
The Scheme is this;
table - user
+---------+-----------+
| user_id | user_name |
+---------+-----------+
| 4 | saif |
| 1 | admin |
| 5 | taqi |
| 2 | rashid |
+---------+-----------+
table - pages
+---------+---------------+
| page_id | page_name |
+---------+---------------+
| 2 | Page 1 |
| 3 | Page 2 |
| 5 | Page 3 |
| 6 | Page 4 |
| 7 | Page 5 |
| 8 | Page 6 |
| 9 | Page 7 |
| 10 | Page 8 |
| 11 | Page 9 |
| 13 | Page 10 |
| 14 | Page 11 |
| 15 | Page 12 |
| 16 | Page 13 |
| 18 | Page 14 |
| 19 | Page 15 |
| 20 | Page 16 |
+---------+---------------+
and table user_privalges for user_id = 1 only.
+--------------------+---------+---------+
| user_privileges_id | user_id | page_id |
+--------------------+---------+---------+
| 1 | 1 | 2 |
| 2 | 1 | 3 |
| 3 | 1 | 5 |
| 4 | 1 | 6 |
| 5 | 1 | 7 |
| 6 | 1 | 8 |
| 7 | 1 | 9 |
| 8 | 1 | 10 |
| 9 | 1 | 11 |
| 10 | 1 | 13 |
| 11 | 1 | 14 |
| 12 | 1 | 15 |
| 13 | 1 | 16 |
| 14 | 1 | 18 |
| 15 | 1 | 19 |
| 16 | 1 | 20 |
+--------------------+---------+---------+
Select up.user_id, p.page_name FROM user_privileges up, pages p where p.page_id = up.page_id and up.user_id = 1 AND up.Assigned=1;
"What I want to get all the pages name and only those are marked that is assigned to that user." So with your edit you should try something like that with case statement
SELECT up.user_id, p.page_name,
CASE
WHEN up.page_id=p.page_id THEN '1'
ELSE '0'
END AS Assigned
FROM pages p left join user_privileges up
ON p.page_id = up.page_id
WHERE up.user_id = 1;
If you are only looking for the user_id = 1 you may do something as
select
1 as user_id,
p.page_name,
case when up.page_id is not null then 1 else 0 end as `Assigned`
from pages p
left join user_privalges up on up.page_id = p.page_id and up.user_id = 1
order by p.page_id
http://www.sqlfiddle.com/#!9/06f65/5

Mysql select distinct id's and select first row only

This is my table. I want to select distinct 'bill_no' with only first related row.
+--------------+--------------+-------+------------+
| id | bill_no | product_name | tax | total |
+--------------+-------+------+-------+------------+
| 1 | 12 | Hairgel | 10 | 241 |
| 2 | 12 | Spiker gel | 10 | 300 |
| 3 | 13 | Wokzem amba | 12 | 450 |
| 4 | 13 | test prod | 1 | 145 |
| 5 | 14 | wokk | 3 | 55 |
| 6 | 14 | Kamer hyp | 11 | 46 |
| 7 | 15 | Xyombokx | 2 | 220 |
+--------------+-------+------+-------+------------+
I want data to be displayed like the below table having only distinct "bill_no" -
Output-
+--------------+--------------+-------+------------+
| id | bill_no | product_name | tax | total |
+--------------+-------+------+-------+------------+
| 1 | 12 | Hairgel | 10 | 241 |
| 3 | 13 | Wokzem amba | 12 | 450 |
| 5 | 14 | wokk | 3 | 55 |
| 7 | 15 | Xyombokx | 2 | 220 |
+--------------+-------+------+-------+------------+
Use group by
select * from youtable group by bill_no
select t1.*
from your_table t1
join
(
select min(id) as id
from your_table
group by bill_no
) t2 on t1.id = t2.id
You can use GROUP BY clause.GROUP BY clause always return first row with related group by cloumn name.
SELECT * FROM `table_1` group by `bill_no`

MYSQL OR two values on one column

I have 2 tables.
Table 1: tA
+----+--------------------+
| id | url |
+----+--------------------+
| 1 | hxxp://www.aaa.com |
| 2 | hxxp://www.bbb.com |
+----+--------------------+
Table 2: tB
+----+-------+--------+----------+
|id | tA_id | cat_id | cat_name |
+----+-------+--------+----------+
| 1 | 1 | 1 | Mobile |
| 2 | 1 | 2 | Other |
| 3 | 2 | 2 | Other |
+----+-------+--------+----------+
Expected Output
+----+-------+--------+----------+
| id | tA_id | cat_id | cat_name |
+----+-------+--------+----------+
| 1 | 1 | 1 | Mobile |
| 3 | 2 | 2 | Other |
+----+-------+--------+----------+
mysql code:
select *
from tA
inner tB
on tA.id = tB.tA_id
where tB.cat_id = 1
or tB.cat_id = 2
Group By tA_id
result from my mysql code:
+----+-------+--------+----------+
| id | tA_id | cat_id | cat_name |
+----+-------+--------+----------+
| 1 | 1 | 2 | Other |
| 3 | 2 | 2 | Other |
+----+-------+--------+----------+
How do I do?
Remove your group by tA_id because it is grouping cat_name Mobile and Other together.
If you need to keep it use ORDER BY tB.cat_id ASC which i believe will show the cat_id 1 and 2 like you need it
There is an error in query... JOIN is missing...
QUERY
SELECT *
FROM tA
INNER JOIN tB
ON tA.id = tB.tA_id
WHERE tB.cat_id = 1
OR tB.cat_id = 2
GROUP BY tA_id
This is fetching expected results
+----+---------------------+-----+--------+--------+----------+
| id | url | id | tA_id | cat_id | cat_name |
+----+---------------------+-----+--------+--------+----------+
| 1 | hxxp://www.aaa.com | 1 | 1 | 1 | mobile |
| 2 | hxxp://www.bbb.com | 3 | 2 | 2 | other |
+----+---------------------+-----+--------+--------+----------+
Try this :-
select *
from tA
inner join tB
on tA.id = tB.tA_id
where tB.cat_id = 1
or tB.cat_id = 2
group by tb.cat_name;
Hope it will help you.

Categories