how can we get multi count values from table? - mysql

I have a database table with these columns: 'dialogue', 'user_id', and 'readed'. I want to count unread messages for every dialogue.
For example:
select count(messageid) from messages where user_id = $id and readed=0 and diyalogid = $diyalog1
select count(messageid) from messages where user_id = $id and readed=0 and diyalogid = $diyalog2
select count(messageid) from messages where user_id = $id and readed=0 and diyalogid = $diyalog3
How can I calculate the count with just one query?

You could do this:
SELECT
SUM(CASE WHEN diyalogid = $diyalog1 THEN 1 ELSE 0 END) AS diyalog1Count,
SUM(CASE WHEN diyalogid = $diyalog2 THEN 1 ELSE 0 END) AS diyalog2Count,
SUM(CASE WHEN diyalogid = $diyalog3 THEN 1 ELSE 0 END) AS diyalog3Count
FROM
messages
WHERE
user_id = $id
AND readed=0
Edit
To answer you comment. I am not really sure what you want. You could do this:
SELECT
COUNT(*) AS theCount,
diyalogid
FROM
messages
WHERE
user_id = $id
AND readed=0
GROUP BY
diyalogid
Then you will have a count per diyalogid

Related

Get both results with one query

I want to get results for likes by a specific user-id and all likes and dislikes of a specific page id.
My structure looks like this:
`pages`: (id, title)
`pages_likes`: (id, page_id, uid, status)
If the status is -1 it's a dislike of a specific page, if it's 1 it's a like.
So, to get all likes this is my query:
SELECT COUNT(id) FROM pages_likes WHERE status = '1'
But now I also want to get if user-id 3 for example likes this page with
SELECT COUNT(id) FROM pages_likes WHERE status = '1' AND uid='3'
How can I achieve both in one query? I guess there has to be changed something right after the SELECT statement?
If you want to do this in a single query, use conditional aggregation:
SELECT SUM(CASE WHEN uid = '3' THEN 1 ELSE 0 END) AS threeLikes,
SUM(CASE WHEN uid <> '3' THEN 1 ELSE 0 END) AS otherLikes
FROM pages_likes
WHERE status = '1'
Another option would be to use a UNION, cf. the answer given by #bernie
Update:
If you want page likes and dislikes in the same query, you can try:
SELECT SUM(CASE WHEN uid = '3' AND status = '1' THEN 1 ELSE 0 END) AS threeLikes,
SUM(CASE WHEN uid <> '3' AND status = '1' THEN 1 ELSE 0 END) AS otherLikes
SUM(CASE WHEN uid = '3' AND status = '0' THEN 1 ELSE 0 END) AS threeDislikes,
SUM(CASE WHEN uid <> '3' AND status = '0' THEN 1 ELSE 0 END) AS otherDisikes
FROM pages_likes
I think this would work:
SELECT '' user, COUNT(id) likes
FROM pages_likes
WHERE status = '1'
GROUP BY 1
UNION ALL
SELECT uid user, COUNT(id) likes
FROM pages_likes
WHERE status = '1' AND uid='3'
GROUP BY 1
I would do it this way:
SELECT COUNT(*) AS total_likes, SUM(uid=3) AS uid3_likes
FROM pages_likes
WHERE status=1 AND page_id=1234
Re your comment:
Here's an example of showing total likes, and total dislikes. It's similar to the answer from #TimBiegeleisen.
SELECT SUM(status=1) AS total_likes,
SUM(CASE WHEN uid=3 AND status=1 THEN 1 END) AS uid3_likes
SUM(CASE WHEN uid=3 AND status=-1 THEN 1 END) AS uid3_dislikes
FROM pages_likes
WHERE page_id=1234

How to count by the value of a column in SQL?

Say I have a table called votes, and a column in that table called vote_type which can either be 0 or 1. How can I fetch the COUNT of vote_type where vote_type is 1?
Right now, I can select the count of vote_type overall, but not the count of vote_type where it is 1 or 0, via this query:
SELECT COUNT(votes.vote_id) AS vote_count
FROM votes
WHERE <some condition>
ORDER BY vote_count
How can I select the total number of vote_types, the number of vote_types = 1, the number of vote_types = 0, and the total vote_value (votetypes = 1 minus votetypes = 0), and order it by the total vote_value?
EDIT: Note that 1 & 0 are not intrinsic values of a vote, but boolean expressions for a positive vote and a negative vote.
I don't know what exactly are you trying to do, but if you want to count all the votes with Vote_Type=1
try
SELECT COUNT(votes.vote_id) AS vote_count
FROM votes
WHERE votes.vote_type=1
or if you need to sum the votes
SELECT SUM(votes.vote_type) AS vote_sum
FROM votes
WHERE votes.vote_type=1
SELECT COUNT(*) TotalVotes,
SUM(CASE WHEN vote_type = 1 THEN 1 ELSE 0 END) TotalVoteOne,
SUM(CASE WHEN vote_type = 0 THEN 1 ELSE 0 END) TotalVoteZero,
SUM(CASE WHEN vote_type = 1 THEN 1 ELSE 0 END) -
SUM(CASE WHEN vote_type = 0 THEN 1 ELSE 0 END) TotalVoteValue
FROM votes
-- WHERE ....
-- ORDER ....
When you say order it by the total vote_value -- it actually doesn't makes sense since the total number of rows in the result is only one.
You can also wrap this in a subquery,
SELECT TotalVotes,
TotalVoteOne,
TotalVoteZero,
(TotalVoteOne - TotalVoteZero) AS TotalVoteValue
FROM
(
SELECT COUNT(*) TotalVotes,
SUM(CASE WHEN vote_type = 1 THEN 1 ELSE 0 END) TotalVoteOne,
SUM(CASE WHEN vote_type = 0 THEN 1 ELSE 0 END) TotalVoteZero
FROM tableName
-- WHERE ....
-- ORDER BY TotalVoteValue DESC
) a
Try to start with something like this:
SELECT SUM(CASE WHEN votetype = 1 then 1 else 0 end) AS vote_count_1,
SUM(CASE WHEN votetype = 0 then 1 else 0 end) AS vote_count_0
FROM votes
WHERE <some condition>
ORDER BY vote_count
Edit: Added a net_vote column, which I think is the "vote1 minus vote0" number you are after.
Select
Sum(Case v.vote_type When 1 then 1 else -1 end) as net_vote
From
Votes v
Where
<some condition>
I've removed the order by, because this is only going to return one row.
$query = "SELECT *FROM votes WHERE vote_type=1 || vote_type=0";
$result = mysql_query($query);
$row = mysql_fetch_assoc($result);
$WhereVoteIsOne=$row['vote_type'];
foreach ($WhereVoteIsOne as $votesCount) { echo $votesCount."<br/>";}

How can I select the rest of the row with DISTINCT?

I have a table where I keep messages and one where I keep users.
I want to get all the users that interactioned (send or received a message) with user_id 1.
This query works:
http://sqlfiddle.com/#!2/6a2f3/1
EDIT:
SELECT DISTINCT
(CASE WHEN `user_to_id` = 1 THEN `user_from_id` ELSE `user_to_id` END) `user_id`,
users.*
FROM `messages`
INNER JOIN users
ON (CASE WHEN `user_to_id` = 1 THEN `user_from_id` ELSE `user_to_id` END) = users.user_id
WHERE `user_to_id` = 1 OR `user_from_id` = 1
ORDER BY `time` DESC
But if I add to SELECT the message column, it returns duplicate records:
http://sqlfiddle.com/#!2/6a2f3/2
EDIT:
SELECT DISTINCT
(CASE WHEN `user_to_id` = 1 THEN `user_from_id` ELSE `user_to_id` END) `user_id`,
`messages`.`message`,
users.*
FROM `messages`
INNER JOIN users
ON (CASE WHEN `user_to_id` = 1 THEN `user_from_id` ELSE `user_to_id` END) = users.user_id
WHERE `user_to_id` = 1 OR `user_from_id` = 1
ORDER BY `time` DESC
How can I fix that?
And also, I see that it orders the results after the "DISTINCT" selection was made. The first query should return the results inverted because the row with message_id 2 has time 3.
Is there a way I can order them before the "DISTINCT"?
EDIT 2: I wasn't clear about the question. I want to select only the last message for a matched user_id.
Do you want something like this?
SELECT *
FROM (
SELECT
users.*,
(SELECT `message` from messages
WHERE
(CASE WHEN `user_to_id` = 1 THEN `user_from_id` ELSE `user_to_id` END) = users.user_id
AND (`user_to_id` = 1 OR `user_from_id` = 1)
ORDER BY `time` DESC limit 1
) AS message
FROM users
) a
WHERE message IS NOT NULL
SQL Fiddle
It's not returning duplicate records, you have two records with User_ID = 2.
I'm confused by what you want them to be ordered by. If you want to order them in the inverted order, just remove 'DESC'

Query with multiple SELECT and GROUP BY

I will count of total area's record where there status will different like 'PENDING','SENT INFO','PTP' with group by and multiple select queries but result not got so plese help me.
My query is:
SELECT AREA,
(SELECT COUNT( * ) FROM prospectmaster WHERE ZONE = 'AHMEDABAD' && STATUS = 'PENDING' GROUP BY AREA) AS PENDING,
(SELECT COUNT( * ) FROM prospectmaster WHERE ZONE = 'AHMEDABAD' && STATUS = 'SENT INFO.' GROUP BY AREA) AS CNT
FROM prospectmaster
WHERE ZONE = 'AHMEDABAD' GROUP BY AREA
I want to this type of result.
AREA PENDING INFO SENT PTP
AHMEDABAD 1 2 1
GANDHINAGAR 1 5 4
KHEDA 3 10 9
I think some problem in query but I doesn't got it.So,Please help me.
SELECT AREA,
SUM(CASE WHEN STATUS = 'PENDING' THEN 1 ELSE 0 END) AS PENDING,
SUM(CASE WHEN STATUS = 'SENT INFO.' THEN 1 ELSE 0 END) AS cnt,
SUM(CASE WHEN STATUS = 'PTP' THEN 1 ELSE 0 END) AS PTP
FROM prospectmaster
WHERE ZONE = 'AHMEDABAD'
GROUP BY AREA;
If STATUS has 'SENT INFO.' record in DB with .
SELECT AREA,
SUM(if(STATUS='PENDING',1,0)) AS PENDING,
SUM(if(STATUS='SENT INFO',1,0)) AS "INFO SENT",
SUM(if(STATUS='PTP',1,0)) AS PTP
FROM prospectmaster
WHERE ZONE = 'AHMEDABAD'
GROUP BY AREA;
Because this is mysql, you can simply do this:
SELECT
AREA,
SUM(STATUS = 'PENDING') AS PENDING,
SUM(STATUS = 'SENT INFO.') AS SENT_INFO,
SUM(STATUS = 'PTP') AS PTP
FROM prospectmaster
WHERE ZONE = 'AHMEDABAD'
GROUP BY AREA
This works because in mysql true is 1 and false is 0, so summing a condition counts how many times its true

MySQL select subqueries

This is what I have at the moment.
$db =& JFactory::getDBO();
$query = $db->getQuery(true);
$query->select('`#__catalog_commit`.`id` as id, `#__catalog_commit`.`date` as date, COUNT(`#__catalog_commit_message`.`commit_id`) as count,
(SELECT COUNT(`#__catalog_commit_message`.`type`) as count_notice FROM `#__catalog_commit_message` WHERE `#__catalog_commit_message`.`type` = 1 GROUP BY `#__catalog_commit_message`.`type`) as count_notice,
(SELECT COUNT(`#__catalog_commit_message`.`type`) as count_warning FROM `#__catalog_commit_message` WHERE `#__catalog_commit_message`.`type` = 2 GROUP BY `#__catalog_commit_message`.`type`) as count_warning,
(SELECT COUNT(`#__catalog_commit_message`.`type`) as count_error FROM `#__catalog_commit_message` WHERE `#__catalog_commit_message`.`type` = 3 GROUP BY `#__catalog_commit_message`.`type`) as count_error');
$query->from('#__catalog_commit_message');
$query->leftjoin('`#__catalog_commit` ON `#__catalog_commit`.`id` = `#__catalog_commit_message`.`commit_id`');
$query->group('`#__catalog_commit_message`.`commit_id`');
$query->order('`#__catalog_commit`.`id` DESC');
What I have is 2 tables with the following structures:
catalog_commit
==============
id
date
catalog_commit_message
======================
id
commit_id
type
message
Basically I want to have the count of each different types of messages per group items. In what I have it actually select every rows (Which is normal) but I'm looking for a way (nicier if possible) to have the count per messages type within the query.
EDIT: Just wanted to add that it's a JModelList.
From what I gather, this should be your query:
SELECT c.id
,c.date
,count(cm.commit_id) as ct_total
,sum(CASE WHEN cm.type = 1 THEN 1 ELSE 0 END) AS count_notice
,sum(CASE WHEN cm.type = 2 THEN 1 ELSE 0 END) AS count_warning
,sum(CASE WHEN cm.type = 3 THEN 1 ELSE 0 END) AS count_error
FROM catalog_commit c
LEFT JOIN catalog_commit_message cm ON cm.commit_id = c.id
GROUP BY c.id, c.date
ORDER BY c.id DESC
You had the order of your tables reversed in the LEFT JOIN. Also, you had weird subqueries in the SELECT list.