unread count and grouping - mysql

I have a very similar setup to this answer Is there a simpler way to achieve this style of user messaging?
However I'm having an issue with getting the total unread conversations and not unread messages.
SELECT p.conversation_id, COUNT(p.conversation_id) as unread
FROM participation AS p
INNER JOIN messages AS m
ON m.conversation_id = p.conversation_id AND m.seen = 0
WHERE p.uid1 = {$user->data['id']}
GROUP BY m.conversation_id`
I'm only selecting p.conversation_id for testing purposes, but the result I am getting is:
Array
(
[conversation_id] => 1
[unread] => 77
)
If I were to put the results in a PHP while loop I get
Array
(
[conversation_id] => 1
[unread] => 77
)
Array
(
[conversation_id] => 3
[unread] => 7
)
Array
(
[conversation_id] => 8
[unread] => 1
)
Array
(
[conversation_id] => 17
[unread] => 35
)
Array
(
[conversation_id] => 22
[unread] => 2
)
Array
(
[conversation_id] => 24
[unread] => 305
)
Array
(
[conversation_id] => 29
[unread] => 41
)
Array
(
[conversation_id] => 31
[unread] => 1
)
The result I am wanting is unread: 8

I think you just want conditional aggregation:
SELECT p.conversation_id,
SUM(m.seen = 0) as unseen,
SUM(m.seen <> 0) as seen
FROM participation AS p INNER JOIN
messages AS m
ON m.conversation_id = p.conversation_id AND m.seen = 0
WHERE p.uid1 = {$user->data['id']}
GROUP BY m.conversation_id
In addition, if you want the total over all conversations, leave out the group by.

Related

How to merge 2 column into 1 column TO output in SQL

I have this sql query:
$sql = "SELECT d.doctor_name, a.patient_name, s.date, s.time FROM appointments AS a LEFT JOIN doctors AS d ON d.id = a.doctor_id LEFT JOIN slots AS s ON s.id = a.slot_id WHERE s.date > '2019-10-01' ORDER BY d.doctor_name DESC ";
$result = $mysqli->query($sql);
echo '<pre>';
while ( $row = $result->fetch_assoc() ) {
print_r($row);
}
echo '</pre>';
and it's output is:
Array
(
[doctor_name] => Khaled
[patient_name] => Nawaz
[date] => 2019-10-11
[time] => 02:01
)
Array
(
[doctor_name] => Khaled
[patient_name] => Anik
[date] => 2019-10-07
[time] => 02:31
)
Array
(
[doctor_name] => Khaled
[patient_name] => Manik
[date] => 2019-10-02
[time] => 03:31
)
Can I merge the date and time column as slot_date_time?
So output will be e.g:
Array
(
[doctor_name] => Khaled
[patient_name] => Manik
[slot_date_time] => 2019-10-02 03:31
)
Try this query
SELECT d.doctor_name, a.patient_name, CONCAT(s.date, ',', s.time) AS slot_date_time
FROM appointments AS a LEFT JOIN doctors AS d
ON d.id = a.doctor_id LEFT JOIN slots AS s
ON s.id = a.slot_id
WHERE s.date > '2019-10-01'
ORDER BY d.doctor_name DESC
Use CONCAT for merge two column as one column

Get month wise count from Mysql database even if there are no results

I am creating graph for display month wise count from Mysql database.
Execute this following query:
$cash_query = $this->db->query("select COUNT(*) as count_monthwise, MONTH(FROM_UNIXTIME(dt_added)) as month from `order` where user_id='1' and status != '9' and payment_type = '1' GROUP BY month");
$cash_result = $cash_query->result();
Output:
Array
(
[0] => stdClass Object
(
[count_monthwise] => 1
[month] => 8
)
[1] => stdClass Object
(
[count_monthwise] => 2
[month] => 9
)
)
In above output, there are display "count_monthwise" means count and month "8" means "8th month - August".
But i want to display output with all months, if find count are 0 in any months, then display [count_monthwise] => 0.
I want to display Exact output like:
Array
(
[0] => stdClass Object
(
[count_monthwise] => 1
[month] => 1
)
[1] => stdClass Object
(
[count_monthwise] => 1
[month] => 2
)
.
.
.
.
.
.
.
[10] => stdClass Object
(
[count_monthwise] => 0
[month] => 11
)
[11] => stdClass Object
(
[count_monthwise] => 0
[month] => 12
)
)
I have used using foreach loop something like this, but this is not working.
Loop
foreach($cash_result as $cash => $cash_value){
for($i=0;$i<=11;$i++){
if($i == $cash){
}
}
}
That could be the one way around:
SELECT
COALESCE(yourQuery.count_monthwise,0) AS monthwise_count,
allMonths.month
(SELECT 1 AS month UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 UNION SELECT 10 UNION SELECT 11 UNION SELECT 12 ) AS allMonths
LEFT JOIN
(
SELECT
COUNT(*) as count_monthwise,
MONTH(FROM_UNIXTIME(dt_added)) as month
from `order`
where user_id='1' and status != '9' and payment_type = '1'
GROUP BY month
) AS yourQuery
ON allMonths.month = yourQuery.month
use below way after getting the result from database don't do complex query just do some code twist
$cash_result = $cash_query->result_array(); // make it to array
$month = range(1,12); // month array
$new_array = array();
$counta = count($month);
for($i=0; $i<$counta ; $i++){
foreach($arr as $key=>$row){
if(($month[$i] == $row['month'])){
$new_array[$i] = $arr[$key];
break;
}else{
$new_array[$i] = array('count_monthwise' => 0,'month' => $month[$i]);
}
}
}
echo '<pre>'; print_r($new_array);

Altering a query to consolidate answers in a poll

I have the following mysql query:
SELECT p.id, p.title, p.description, a.id, a.answer, q.id, q.question
FROM x_trybe_poll_relation pr
LEFT JOIN x_polls p
ON pr.poll_id = p.id
LEFT JOIN x_polls_question_relation qr
ON p.id = qr.poll_id
LEFT JOIN x_polls_questions q
ON qr.question_id = q.id
LEFT JOIN x_polls_answers a
ON q.id = a.question_id
WHERE pr.trybe_id = '%s'
Which returns:
[polls] => Array
(
[0] => Array
(
[id] => 79de13af1978ab14f56b4305956b2d93cd42e0fb
[title] => Poll 1
[description] => Poll 1 Description
[answer] => Danny Welbeck
[question] => Who is the best player in the Arsenal squad?
)
[1] => Array
(
[id] => 79de13af1978ab14f56b4305956b2d93cd42e0fb
[title] => Poll 1
[description] => Poll 1 Description
[answer] => Alexis Sanchez
[question] => Who is the best player in the Arsenal squad?
)
)
How do I adjust the mysql query to get the following:
[polls] => Array
(
[0] => Array
(
[id] => 79de13af1978ab14f56b4305956b2d93cd42e0fb
[title] => Poll 1
[description] => Poll 1 Description
[answers] => Array (
[0] => Array (
[id] => abc
[answer] => Danny Welbeck
)
[1] => Array (
[id] => def
[answer] => Alexis Sanchez
)
)
[question] => Who is the best player in the Arsenal squad?
)
)
I want to get the poll question, and get the array of pre-generated answers with one query.
Is this possible, or should I just run two queries?
Thanks

MySQL Replace string SUM then total

Looking to get a total for each ID from the sum of the replacement fields.
SELECT
insurance_carrier as ID, SUM(REPLACE(REPLACE(REPLACE(es_reserve,'$',''),',',''),'-','')) AS es_reserve,
SUM(REPLACE(REPLACE(REPLACE(structure_reserve,'$',''),',',''),'-',''))AS structure_reserve,
SUM(es_reserve+structure_reserve) AS total
FROM job_tbl
WHERE
job_status NOT IN(2,4,6,7,9) AND
insurance_carrier !=0 AND
FROM_UNIXTIME(date_of_loss,'%m') = MONTH(NOW()) AND
FROM_UNIXTIME(date_of_loss,'%Y') = YEAR(NOW())
GROUP BY insurance_carrier
I get the results from es_reserve and structure_reserve but the total is 0.
BTW the fields contain items like $2,300- that's the reason for the replace
Any help would be appreciated!!!
EDIT: here is the results this produces
Array
(
[ID] => 14
[es_reserve] => 5000
[structure_reserve] => 35000
)
Array
(
[ID] => 15
[es_reserve] => 2500
[structure_reserve] => 2500
)
Array
(
[ID] => 41
[es_reserve] => 2500
[structure_reserve] => 2500
)
Array
(
[ID] => 44
[es_reserve] => 2500
[structure_reserve] =>
)
Here is what I would like it to produce
Array
(
[ID] => 14
[es_reserve] => 5000
[structure_reserve] => 35000
[total] => 40000
)
Array
(
[ID] => 15
[es_reserve] => 2500
[structure_reserve] => 2500
[total] => 5000
)
Array
(
[ID] => 41
[es_reserve] => 2500
[structure_reserve] => 2500
[total] => 5000
)
Array
(
[ID] => 44
[es_reserve] => 2500
[structure_reserve] =>
[total] => 2500
)
Total column is doing sum on original column value , the alias name defined in the select won't be used in the same select.
You can repeat replace statement while doing total column computation
SUM( REPLACE(REPLACE(REPLACE(es_reserve,'$',''),',',''),'-','')
+ REPLACE(REPLACE(REPLACE(structure_reserve,'$',''),',',''),'-',''))
Total,
instead of
SUM(es_reserve+structure_reserve) as total
The query becomes, with order by as asked in comment.
SELECT insurance_carrier as ID, SUM(REPLACE(REPLACE(REPLACE(es_reserve,'$',''),',',''),'-','')) AS es_reserve, SUM(REPLACE(REPLACE(REPLACE(structure_reserve,'$',''),',',''),'-',''))AS structure_reserve, SUM( REPLACE(REPLACE(REPLACE(es_reserve,'$',''),',',''),'-','') + REPLACE(REPLACE(REPLACE(structure_reserve,'$',''),',',''),'-','')) as Total FROM job_tbl WHERE job_status NOT IN(2,4,6,7,9) AND insurance_carrier !=0 AND FROM_UNIXTIME(date_of_loss,'%m') = MONTH(NOW()) AND FROM_UNIXTIME(date_of_loss,'%Y') = YEAR(NOW()) GROUP BY insurance_carrier
order by SUM( REPLACE(REPLACE(REPLACE(es_reserve,'$',''),',',''),'-','') + REPLACE(REPLACE(REPLACE(structure_reserve,'$',''),',',''),'-','')) desc
OR
use it as subquery
SELECT T.*, SUM(es_reserve+structure_reserve) AS total
FROM
(
SELECT
insurance_carrier as ID, SUM(REPLACE(REPLACE(REPLACE(es_reserve,'$',''),',',''),'-','')) AS es_reserve,
SUM(REPLACE(REPLACE(REPLACE(structure_reserve,'$',''),',',''),'-',''))AS structure_reserve
FROM job_tbl
WHERE
job_status NOT IN(2,4,6,7,9) AND
insurance_carrier !=0 AND
FROM_UNIXTIME(date_of_loss,'%m') = MONTH(NOW()) AND
FROM_UNIXTIME(date_of_loss,'%Y') = YEAR(NOW())
GROUP BY insurance_carrier
) T

mysql union and group by similar fields

Here is my query (I replaced table names with generic ones). I am trying to do a union all on two different queries in order to group them all by date so that results with similar dates come out as one row.
I am getting the "Every derived table must have its own alias" error when attempting to execute. What am I typing in wrong?
I have researched this but couldn't find the answer. Every selected field has an alias? Or is the issue in the first SELECT?
SELECT SUM(val), id, dat, title FROM (
SELECT table1.product_id as id, SUM(table1.qty) as val, DATE_FORMAT(table1.created, '%Y-%m-1') as dat, table2.title as title
FROM table1
LEFT JOIN table3 ON table1.event_id = table3.id
LEFT JOIN table2 ON table1.product_id = table2.id
WHERE table1.user_id = $user_id AND table3.active != 2 AND table3.temp = 0 AND table2.active != 2
GROUP BY dat
UNION ALL
SELECT table4.product_id as id, SUM(table4.qty) as val, DATE_FORMAT(table4.created, '%Y-%m-1') as dat, table2.title as title
FROM table4
LEFT JOIN table5 ON table4.festival_id = table5.id
LEFT JOIN table2 ON table4.product_id = table2.id
WHERE table4.user_id = $user_id AND table5.active != 2 AND table2.active != 2
GROUP BY dat
)
GROUP BY id
ORDER BY dat ASC
Here is what I am attempting to do:
My original result:
Array
(
[0] => stdClass Object
(
[id] => 1
[val] => 1
[dat] => 2012-05-1
[title] => Test Product
)
[1] => stdClass Object
(
[id] => 1
[val] => 8
[dat] => 2012-06-1
[title] => Test Product
)
[2] => stdClass Object
(
[id] => 2
[val] => 4
[dat] => 2012-06-1
[title] => Test Product 2
)
[3] => stdClass Object
(
[id] => 3
[val] => 6
[dat] => 2012-06-1
[title] => Test Product 3
)
[4] => stdClass Object
(
[id] => 1
[val] => 10
[dat] => 2012-05-1
[title] => Test Product
)
[5] => stdClass Object
(
[id] => 1
[val] => 8
[dat] => 2012-06-1
[title] => Test Product
)
[6] => stdClass Object
(
[id] => 2
[val] => 3
[dat] => 2012-06-1
[title] => Test Product 2
)
[7] => stdClass Object
(
[id] => 3
[val] => 3
[dat] => 2012-06-1
[title] => Test Product 3
)
)
So if they have a similar date and ID, I need those to be just one result. Like so:
Array
(
[0] => stdClass Object
(
[id] => 1
[val] => 11
[dat] => 2012-05-1
[title] => Test Product
)
[1] => stdClass Object
(
[id] => 1
[val] => 8
[dat] => 2012-06-1
[title] => Test Product
)
[2] => stdClass Object
(
[id] => 2
[val] => 7
[dat] => 2012-06-1
[title] => Test Product 2
)
[3] => stdClass Object
(
[id] => 3
[val] => 9
[dat] => 2012-06-1
[title] => Test Product 3
)
)
Please let me know if you need anything else. Thanks in advance.
Try this:
SELECT SUM(val), id, dat, title FROM (
SELECT table1.product_id as id, SUM(table1.qty) as val, DATE_FORMAT(table1.created, '%Y-%m-1') as dat, table2.title as title
FROM table1
LEFT JOIN table3 ON table1.event_id = table3.id
LEFT JOIN table2 ON table1.product_id = table2.id
WHERE table1.user_id = $user_id AND table3.active != 2 AND table3.temp = 0 AND table2.active != 2
GROUP BY dat
UNION ALL
SELECT table4.product_id as id, SUM(table4.qty) as val, DATE_FORMAT(table4.created, '%Y-%m-1') as dat, table2.title as title
FROM table4
LEFT JOIN table5 ON table4.festival_id = table5.id
LEFT JOIN table2 ON table4.product_id = table2.id
WHERE table4.user_id = $user_id AND table5.active != 2 AND table2.active != 2
GROUP BY dat
) AS t
GROUP BY id, dat
ORDER BY dat ASC
As the error suggests, every view/derived table must have an alias..
Edit: This will give you records with distinct id/dat pair. Seems this is what is you are after.