Insert `COUNT(*)` based on separate table - php

In MySQL is it possible to select columns from one table while also creating a column for COUNT(*) based on other tables? That way a summary of the results from all tables can be returned. This might be a bit confusing to explain in words so I made some sample tables instead:
events_tbl
----------------------------
id | eventname
1 | Anime Festival
2 | Food Festival
----------------------------
booths_tbl
-------------------------
id | boothname
1 | Walmart
2 | Pizza Hut
3 | Nike
4 | North Face
-------------------------
participants_tbl
-----------------------------
id | participantname
1 | John
2 | Mike
3 | Rambo
4 | Minnie
-----------------------------
event_booths_tbl
--------------------------------
event_id | booth_id
1 | 1
1 | 2
1 | 5
2 | 3
2 | 4
--------------------------------
event_participants_tbl
-------------------------------------
event_id | booth_id
1 | 1
1 | 2
1 | 3
1 | 4
-------------------------------------
Is there a way to get results like this in MySQL:
summary_tbl
------------------------------------------------------------------------
id | eventname | booth_count | participant_count
1 | Anime Festival | 3 | 4
2 | Food Festival | 2 | 0
------------------------------------------------------------------------

The event_participants_tbl should contain participant_id instead of booth_id.
Its irrelevant otherwise.
Your MySQL query would be like this :
select
et.id,
et.eventname,
count(distinct ebt.booth_id) as booth_count,
count(distinct ept.participant_id) as participant_count
from
event_booths_tbl ebt
left join events_tbl et on et.id=ebt.event_id
left join event_participants_tbl ept on ept.event_id=ebt.event_id
group by et.event_id;

Join with subqueries that count in each table:
SELECT e.id, e.event_name,
IFNULL(b.booth_count, 0) AS booth_count,
IFNULL(p.participant_count, 0) AS participant_count
FROM events_table AS e
LEFT JOIN (SELECT event_id, COUNT(*) AS booth_count
FROM event_booths_table
GROUP BY event_id) AS b ON e.id = b.event_id
LEFT JOIN (SELECT event_id, COUNT(*) AS participant_count
FROM event_participants_table
GROUP BY event_id) AS p ON e.id = p.event_id

Try this :
select event.id,
event.name,
count(distinct eventBooth.booth_id),
count(distinct eventParitcipant.booth_id)
from events_tbl event
LEFT JOIN event_booths_tbl eventBooth on eventBooth.event_id=event.id
LEFT JOIN event_participants_tbl eventParitcipant
on eventParitcipant.event_id=event.id
group by event.id

Related

INNERJOIN WITH COUNT DISTINCT [duplicate]

I have a tagging system for my events system I would like to create a 'tag cloud'.
I have Events, which can have multiple 'categories'.
Here's the table structure:
**Event_Categories** (Stores Tags / Categories)
| id | name |
+-----------------+
+ 1 | sport |
+ 2 | charity |
+ 3 | other_tag |
**Events_Categories** (Linking Table)
| event_id | event_category_id |
+-------------------------------+
+ 1 | 1 |
+ 2 | 2 |
+ 3 | 1 |
+ 3 | 2 |
Summary:
Event ID 1 -> Sport
Event ID 2 -> Charity
Event ID 3 -> Sport, Charity
I'd like to return the following:
| tag_name | occurrences |
+-----------+-------------+
| sport | 2 |
| society | 2 |
other_tag - Not actually returned, as it has 0 occurrences
Thanks! :)
this will work:
SELECT c.name AS tag_name, COUNT(ec.event_id) AS occurrences
FROM Event_Categories c
INNER JOIN Events_Categories ec ON c.id = ec.event_category_id
GROUP BY c.id
change the INNER JOIN to LEFT JOIN if you want to include categories with 0 occurances
How about something like
SELECT e.name,
COUNT(1)
FROM Event_Categories e INNER JOIN
Events_Categories_Linking ec ON e.id = ec.event_category_id
GROUP BY e.name
SQL Fiddle DEMO

PDO Query : Count related and repeated values then inner join

I work with PHP and PDO.
So I have 2 tables like,
Table 1
| id | name | age |
| 1 | John | 25 |
| 2 | Tom | 32 |
| 3 | James| 45 |
Table 2
| id | Comment | Link |
| 1 | some text | 3 |
| 2 | some text | 3 |
| 3 | some text | 1 |
So, Link column numbers represent id's in table1. For example Link = 3s in table 2 represent James in table 1. I need a query which brings all table1's data and also a number of repeated value for related Link column which comes from table2.
For example, the query should give me (let's choose James),
| id | name | age | Value |
| 3 | James | 45 | 2 |
value=2, because there are two 3s in link column which related to James
I tried somethings but got lots of errors.
I think you just need the GROUP BY
SELECT a.id,
a.name,
a.age,
count(*) as value
FROM table1 a
JOIN table2 b ON a.id = b.link
GROUP BY a.id, a.name, a.age
If you really want just one row then add WHERE
SELECT a.id,
a.name,
a.age,
count(*) as value
FROM table1 a
JOIN table2 b ON a.id = b.link
WHERE a.name = 'James'
GROUP BY a.id, a.name, a.age
or use subquery
SELECT a.id,
a.name,
a.age,
(SELECT count(*) FROM table2 b WHERE a.id = b.link) as value
FROM table1 a
WHERE a.name = 'James'

mysql query to get all reviews for every company

I have a database with tables like below:
Reviews
id | review | companyid
companies
id | name
Now i want to get the data back so that i can show each company name with the total number of reviews for the company. Like seen below:
company 1 (company name) | 345
company 2 (company name) | 28
company 3 (company name) | 794
From here i will make a table using php to display the results
How can i achieve this with MYSQl?
Try this way:
SELECT Count(`r`.`review`) AS `total_reviews`,
`c`.`company`
FROM `reviews` AS `r`
JOIN `companies` AS `c`
ON `c`.`id` = `r`.`companyid`
Use COUNT and GROUP BY to count the reviews per company and use JOIN to get the company name from the other table.
Query
select t2.name as companyName,coalesce(t1.`count`,0) as `count` from
(
select companyid,count(companyid) as `count`
from reviews
group by companyid
)t1
right join companies t2
on t1.companyid= t2.id;
Sample Output
Table - reviews
+----+--------+-----------+
| id | review | companyid |
+----+--------+-----------+
| 1 | r1 | 1 |
| 2 | r2 | 2 |
| 3 | r3 | 1 |
+----+--------+-----------+
Table - companies
+----+------+
| id | name |
+----+------+
| 1 | C1 |
| 2 | C2 |
| 3 | C3 |
+----+------+
Output
+------+-------+
| name | count |
+------+-------+
| C1 | 2 |
| C2 | 1 |
| C3 | 0 |
+------+-------+
SQL Fiddle
You need to use a GROUP BY
SELECT r.companyid, c.name, count(r.id) as nb_review
FROM reviews r
INNER JOIN companies c ON (r.companyid = c.id)
GROUP BY r.companyid, c.name;
If you also want to see the companies with no reviews, do :
SELECT c.id, c.name, count(r.id) as nb_review
FROM companies c
LEFT JOIN reviews r ON (r.companyid = c.id)
GROUP BY c.id, c.name;

join one row from one mysql table to multiple row in second table

I have question about mysql queries. The story goes something like this: I have table in which I store information about college trips. This table has attributes about name of a trip, id of a trip and activity. Activity can be 0 or 1, depending if trip is still active (1) or inactive (0). In second table I have information about students that have applied for trips with attributes: id, name, surname and id of a trip that student have applied for. I don't know mysql query that will show me only students that have applied for trips that are still active (acitivity=1).
For example let's have a look at these tables:
TRIPS
id | trip | activity
---+----------+-----------
1 | Paris | 0
2 | London | 1
3 | Belgrade | 0
4 | Prague | 1
STUDENTS
id | name | id_trip
---+----------+-----------
1 | Mark | 3
2 | Ana | 1
3 | Tom | 2
4 | Maya | 3
5 | Rachel | 4
6 | John | 2
RESULT
id | name | id_trip | trip | activity
---+----------+---------+---------+---------
3 | Tom | 2 | London | 1
5 | Rachel | 4 | Prague | 1
6 | John | 2 | London | 1
SELECT
s.id,
s.name,
s.id_trip,
t.trip,
t.activity
FROM
STUDENTS AS s
INNER JOIN TRIPS AS t ON ( t.id = s.id_trip )
WHERE
t.id = 1
hope this will work.
Try this:
SELECT s.id, s.name, s.id_trip, t.name, t.activity
FROM students s
JOIN trips t
ON s.id_trip = t.id
WHERE t.activity = 1
select * from students s
join trips t
on s.id_trip = t.id
where t. activity =1
Try this it may solve your problem:
select s.id as id, s.name as name,t.trip as trip,
t.activity as activity from trips t
join students s on
t.id = s.id_trip
where t.activity = 1

PHP MYSQL query a join table for to get last row for parent table query

I have two tables : ticket & history_ticket
Table ticket :
ticket_id | ticket_desc
1 | software
2 | hardware
3 | other
Table history_ticket :
history_id | ticket_id | message | status
1 | 1 | text | process
2 | 2 | text | solve
3 | 3 | text | process
4 | 3 | text | solve
I want result like this
ticket_id | ticket_desc | status
1 | software | process
2 | hardware | solve
3 | other | solve
I've tried various joins and subselects, but no luck
Any help/directions will be much appreciated!
UPDATE : How if i change the result, like this
ticket_id | ticket_desc | last_status | count_message
1 | software | process | 1
2 | hardware | solve | 1
3 | other | solve | 2
Try this:
SELECT
t.ticket_id,
ticket_desc,
ht.status
FROM ticket AS t
INNER JOIN history_ticket AS ht ON t.ticket_id = ht.ticket_id
INNER JOIN
(
SELECT ticket_id, MAX(history_id) maxid
FROM history_ticket
GROUP BY ticket_id
) AS ht2 ON ht.history_id = ht2.maxid;
SQL Fiddle Demo
This will give you:
| TICKET_ID | TICKET_DESC | STATUS |
-------------------------------------
| 1 | software | process |
| 2 | hardware | solve |
| 3 | Problem | solve |
UPDATE 1
To get the count of messages for each ticket, you can simply include COUNT(history_id) AS sum_message in the subquery like this:
SELECT
t.ticket_id,
ticket_desc,
ht.status,
ht2.sum_message
FROM ticket AS t
INNER JOIN history_ticket ht ON t.ticket_id = ht.ticket_id
INNER JOIN
(
SELECT
ticket_id,
MAX(history_id) maxid,
COUNT(history_id) AS sum_message
FROM history_ticket
GROUP BY ticket_id
) AS ht2 ON ht.history_id = ht2.maxid;
Updated SQL Fiddle Demo
This will give you:
| TICKET_ID | TICKET_DESC | STATUS | SUM_MESSAGE |
---------------------------------------------------
| 1 | software | process | 1 |
| 2 | hardware | solve | 1 |
| 3 | Problem | solve | 2 |
Update 2
If you want to select names for the ids divisi_id, for simple values, you can use the CASE expression for this:
SELECT
t.ticket_id,
ticket_desc,
CASE
WHEN t.divisi_id = 101 THEN 'Divisi A'
WHEN t.divisi_id = 102 THEN 'Divisi B'
END AS 'Divisi',
ht.status,
ht2.sum_message
FROM ticket AS t
INNER JOIN history_ticket ht ON t.ticket_id = ht.hticket_id
INNER JOIN
(
SELECT hticket_id, MAX(history_id) maxid, COUNT(history_id) AS sum_message
FROM history_ticket
GROUP BY hticket_id
) AS ht2 ON ht.history_id = ht2.maxid;
Updated SQL Fiddle Demo
This will give you:
| TICKET_ID | TICKET_DESC | DIVISI | STATUS | SUM_MESSAGE |
--------------------------------------------------------------
| 1 | software | Divisi A | process | 1 |
| 2 | hardware | Divisi B | solve | 1 |
| 3 | Problem | Divisi A | solve | 2 |
For multiple values, you can put them in a temp table, or you can select them in a subquery and join the table to get the name like this:
SELECT
t.ticket_id,
ticket_desc,
d.Divisi,
ht.status,
ht2.sum_message
FROM ticket AS t
INNER JOIN history_ticket ht ON t.ticket_id = ht.hticket_id
INNER JOIN
(
SELECT hticket_id, MAX(history_id) maxid, COUNT(history_id) AS sum_message
FROM history_ticket
GROUP BY hticket_id
) AS ht2 ON ht.history_id = ht2.maxid
INNER JOIN
(
SELECT 101 AS divisi_id, 'Divisi A' AS Divisi
UNION ALL
SELECT 102 , 'Divisi B'
... -- here you put other values or you can join a temp table instead
) AS D ON t.divisi_id = D.divisi_id;
Updated SQL Fiddle Demo
select distinct ticket.ticket_id, ticket.ticket_desc, history_ticket.status
from ticket
join history_ticket on ticket_id
This, as far as I remember, will choose a description and status at random if you have more than one. If you want to apply a specific rule to which one to pick, give more info and we can help you on that.
Try
SELECT DISTINCT
tk.ticket_id,
tk.ticket_desc,
ht.status
FROM ticket tk JOIN history_ticket ht ON tk.ticket_id = tk.ticket_id
ORDER BY tk.ticket_id
Try,
Select distinct t.ticket_id, t.ticket_desc, h.status
from ticket t, history_ticket h
where t.ticket_id = h.ticket_id
order by t.ticket_id

Categories