Get both results with one query - mysql

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

Related

MySQL Query for selecting multiple count Column

I have a table like this-
I want to run a query so that I can have a output like it-
I don't have a clear idea how to do it.
So, what I have done is-
SELECT
Count(* where status="Active") as count_active
Count(* where status="Inctive") as count_inactive
Count(* where status="Biase") as count_biase
FROM `subscribers`
And getting error, can anyone please help?
Can achieve this with a Case expression.
Query
select
count(case when status = 'Active' then 1 else null end) as Active_Count,
count(case when status = 'Inactive' then 1 else null end) as Inctive_Count,
count(case when status = 'Biase' then 1 else null end) as Biase_Count
from tbl_name;
SQL Fiddle
This is the way to put it in a single register:
SELECT
(SELECT count(id) FROM new_table where status = 'Active') as Active_Count,
(SELECT count(id) FROM new_table where status = 'Inactive') as Inctive_Count,
(SELECT count(id) FROM new_table where status = 'Biase') as Biase_Count;

How to select count(distinct) with additional where clause in MySQL?

I have a query that looks like this:
SELECT clicks.offer_id, count(distinct clicks.transaction_id) as unique_clicks
FROM clicks
WHERE date > '2014-12-01 17:43:30' and offer_id = 1;
This query counts the number of unique clicks by their transaction ID for an offer.
Now, I want to add the unique number of clicks for mobile and desktop users. Along the lines of:
SELECT clicks.offer_id, count(distinct clicks.transaction) as unique_clicks,
sum(case when clicks.mobile = 1 then 1 else 0 end) as mobile_unique_clicks,
sum(case when clicks.mobile = 0 then 1 else 0 end) as desktop_unique_clicks
FROM clicks
WHERE date > '2014-12-01 17:43:30' and offer_id = 1;
The problem with this is that it won't count unique transaction IDs. Is there a way to do this with one query? And what kind of covering indexes would I need to keep this efficient?
SELECT clicks.offer_id, count(distinct clicks.transaction_id) as unique_clicks,
count(DISTINCT case when clicks.mobile = 1 then clicks.transaction_id else null end) as mobile_unique_clicks,
count(DISTINCT case when clicks.mobile = 0 then clicks.transaction_id else null end) as desktop_unique_clicks
FROM clicks
WHERE date > '2014-12-01 17:43:30' and offer_id = 1;
You can use COUNT(DISTINCT ...)
something like this?
SELECT clicks.offer_id,
count(distinct clicks.transaction_id) as unique_clicks,
sub.mobile_unique_clicks,
count(distinct clicks.transaction_id) - sub.mobile_unique_clicks as desktop_unique_clicks
FROM clicks
JOIN
(
SELECT clicks.offer_id, count(distinct clicks.transaction_id) as mobile_unique_clicks,
FROM clicks
WHERE date > '2014-12-01 17:43:30' and offer_id = 1 AND clicks.mobile = 1
) sub
WHERE date > '2014-12-01 17:43:30' and offer_id = 1;
If I'm understanding your question correctly, you can move your query to a subquery and use distinct:
select offer_id,
count(transaction) unique_clicks,
count(case when mobile = 1 then 1 end) mobile_unique_clicks,
count(case when mobile = 0 then 1 end) desktop_unique_clicks
from (
select distinct offer_id, transaction, mobile
from clicks
where date > '2014-12-01 17:43:30' and offer_id = 1
) t
group by offer_id

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/>";}

Sum record between two dates for different users in mysql query Issue

I have two tables lead and lead_details. There is a field status. If status=1 is open, status=2 is close and status=3 is not specified.
I want to find sum of all Open,close and not specified for each user/agent.
Here is what I tried but it give me wrong data
select agent_id,
type,
status,
created_date,
category_id,
sum(case when status = 2 then val else 0 end) as closed1,
sum(case when status = 1 then val else 0 end) as opened1,
sum(case when status = 3 then val else 0 end) as notspecefied1
from ( select l.agent_id,
l.type,
ld.category_id,
l.status,
l.created_date,
count(*) as val
from crm_leads l,
crm_leads_details ld
where l.id=ld.lead_id AND
status in (2, 1, 3)
GROUP BY status, agent_id
) t
WHERE created_date BETWEEN '2013-8-2' AND '2013-9-2'
GROUP BY agent_id
You need to put the WHERE created_date clause in the subquery.
select agent_id,type,status,created_date,category_id,
sum(case when status = 2 then val else 0 end) as closed1,
sum(case when status = 1 then val else 0 end) as opened1,
sum(case when status = 3 then val else 0 end) as notspecefied1
from ( select l.agent_id,l.type,ld.category_id,l.status,l.created_date,
count(*) as val from crm_leads l JOIN crm_leads_details ld
ON l.id=ld.lead_id
WHERE created_date BETWEEN '2013-8-2' AND '2013-9-2' AND status in (2, 1, 3)
GROUP BY status, agent_id ) t
GROUP BY agent_id
Note that the created_date in the result will just be a randomly selected date in the period for each agent.

How to combine two count queries to their ratio?

I have two queries:
select count(*) from my_table where status="accepted"
and
select count(*) from my_table where status="rejected"
I was to find the ratio of accepted/reject so I Was wondering if it's possible to combine the two queries so I don't have to execute two queries
Putting this answer since none offered so far is correct
select count(case when status = "accepted" then 1 end) /
count(case when status = "rejected" then 1 end) as Ratio
from my_table
where status in ("accepted","rejected")
If you also need the individual counts
select count(case when status = "accepted" then 1 end) Accepted,
count(case when status = "rejected" then 1 end) Rejected,
count(case when status = "accepted" then 1 end) /
count(case when status = "rejected" then 1 end) as Ratio
from my_table
where status in ("accepted","rejected")
Note: MySQL does not have a divide by zero problem. It returns NULL when Rejected is 0.
select accepted_count, rejected_count, accepted_count/rejected_count ratio
from (
select sum(CASE WHEN status="accepted" THEN 1 ELSE 0 END) accepted_count,
sum(CASE WHEN status="rejected" THEN 1 ELSE 0 END) rejected_count
from my_table
) A
I think this will work:
SELECT (Select count(*) from my_table where status="accepted") / (select count(*) from my_table where status="rejected") AS ratio
select status, count(*) from my_table
where status in ("rejected", "accepted")
group by status;
select sum(case when status='accepted' then 1 else 0 end) as AcceptedCount,
sum(case when status='rejected' then 1 else 0 end) as RejectedCount
from my_table