Group sql query - php

I want to have an only query with 2 queries but i don't know how to start...
My queries count the positive/negative votes for a comment.
SELECT COUNT(id) AS votes_no FROM comments_votes WHERE vote = 0 AND id_comment = 1
SELECT COUNT(id) AS votes_no FROM comments_votes WHERE vote = 1 AND id_comment = 1
I set vars to put negative and positives votes : $votes_no and $votes_yes
Then i have a final var : $votes_calc = $votes_yes - $votes_no;
How can i get the number of votes_yes, votes_no and votes_calc in only one query?
Thanks a lot!

select votes_no, votes_yes, votes_yes-votes_no as votes_calc
from (select sum(case when vote = 0 then 1 else 0 end) as votes_no,
sum(case when vote = 1 then 1 else 0 end) as votes_yes
from comments_votes
where id_comment = 1) a

select vote,count(id)
from Comment_votes
group by vote
WHERE id_comment = 1
with rollup
The with Rollup will add a row with a NULL value in the vote column and the total in the second column

I merge the query getting the comments and the comments votes and it seems to work :)
SELECT a.*, nb_votes, votes_yes-votes_no AS votes_calc
FROM comments AS a
LEFT JOIN (
SELECT id_comment, COUNT(id) AS nb_votes,
SUM(CASE WHEN vote = 0 THEN 1 ELSE 0 END) AS votes_no,
SUM(CASE WHEN vote = 1 THEN 1 ELSE 0 END) AS votes_yes
FROM comments_votes GROUP BY id_comment
) AS c ON (a.id = c.id_comment)
WHERE a.status = 'approved' AND a.id_post = 1 ORDER BY a.time ASC
Thanks for your answers :)

Related

Need to show SQL partial empty results

I need to show empty rows for BRANDS too. I mean, there is a third brand not shown in this query, look:
SELECT
da_brands.name AS brand_name,
COUNT(DISTINCT da_deals.id) AS total_deals,
0 AS total_downloaded_coupons,
0 AS total_validated_coupons,
COUNT(da_logs.id) AS total_likes
FROM
da_brands,
da_deals
LEFT JOIN da_logs
ON da_logs.fk_deal_id = da_deals.id
AND da_logs.fk_deal_id = da_deals.id
AND da_logs.type = 'deal_like'
WHERE da_brands.fk_club_id = 6
AND da_deals.fk_brand_id = da_brands.id
AND da_brands.date <= NOW()
GROUP BY da_brands.name
ORDER BY da_brands.name ASC
RESULTS:
brand_name total_deals total_downloaded_coupons total_validated_coupons total_likes
Marca2 2 0 0 1
Marca1 9 0 0 4
This conditional is showing only brands within deals but i want all brands...:
AND da_deals.fk_brand_id = da_brands.id
Any idea what statement should i use?
Thank you so much.!!!
This following line in the WHERE predicate is the problem...
AND da_deals.fk_brand_id = da_brands.id
You need to LEFT JOIN to da_deals, the same way you did to da_logs, and move that line above into the ON statement for the join.
See below...
SELECT
da_brands.name AS brand_name,
COUNT(DISTINCT da_deals.id) AS total_deals,
0 AS total_downloaded_coupons,
0 AS total_validated_coupons,
COUNT(da_logs.id) AS total_likes
FROM da_brands
LEFT JOIN da_deals
ON da_brands.id = da_deals.fk_brand_id
LEFT JOIN da_logs
ON da_logs.fk_deal_id = da_deals.id
AND da_logs.fk_deal_id = da_deals.id
AND da_logs.type = 'deal_like'
WHERE da_brands.fk_club_id = 6
AND da_brands.date <= NOW()
GROUP BY da_brands.name
ORDER BY da_brands.name ASC

MySQL alias calculation

It confuses me.. total left calculation seems doesn't work.
I am trying to get the total voucher and get total used and the total left.
please help.
SELECT
(IFNULL(SUM(value), 0)) AS total_voucher,
(
SELECT
IFNULL(SUM(value), 0))
FROM
voucher_history
WHERE
idUser = 1 AND isUsed = 1 AND DATE(FROM_UNIXTIME(datetime)) = '2014-03-04'
) AS total_used,
(total_voucher-total_used) AS total_left
FROM
voucher_history
WHERE
idUser = 1 AND isUsed = 0 AND DATE(FROM_UNIXTIME(datetime)) <= '2014-03-05'
You can do this with conditional aggregation, rather than using a subquery:
SELECT coalesce(SUM(value), 0)) AS total_voucher,
sum(case when is_used = 1 then value else 0 end) as total_used,
sum(case when is_used = 1 then 0 else value end) as total_left
FROM voucher_history
WHERE idUser = 1 AND DATE(FROM_UNIXTIME(datetime)) <= '2014-03-05';
Your query has the problem that it is trying to use column aliases (total_voucher and total_used) in the same select statement. SQL does not support this. You would need to use a subquery to get that functionality.

MySQL pivot with multiple counts

This is a snapshot of my MySQL table:
Is it possible to write a query to get such a pivot table like output...
How about something like
SELECT url_host,
SUM(CASE WHEN post_id = -1 THEN 1 ELSE 0 END) as post_id_minus1,
SUM(CASE WHEN post_id = 0 THEN 1 ELSE 0 END) as post_id_0,
etc...
FROM YOUR_TABLE
GROUP BY url_host
You can use CASE statement on this to pivot your table.
SELECT url_host,
COUNT(CASE WHEN post_ID = -1 THEN 1 ELSE NULL END) Negative_One,
COUNT(CASE WHEN post_ID = 0 THEN 1 ELSE NULL END) Zero,
COUNT(CASE WHEN post_ID > 0 THEN 1 ELSE NULL END) Greater_Zero
FROM tableName
GROUP BY url_host
SQLFiddle Demo

Can I select more counts in one query?

I have a table with a field called type, where 3 various rows are possible: 1, 2 and 3.
Now, I don't care about 3 at all. I need to count how many rows there are with type = 1 and with type = 2. I am doing this with 2 queries, like this:
Query1: SELECT COUNT(id) as count FROM users WHERE type='1'
Query2: SELECT COUNT(id) as count FROM users WHERE type='2'
Can I do this with only 1 single query? If so, should I, or not? How would the query look?
SELECT type,
COUNT(id) AS count
FROM users
WHERE type IN ('1','2')
GROUP BY type
SELECT type, COUNT(id) AS count
FROM users
GROUP BY type
HAVING type < 3
SELECT sum(case when type = '1' then 1 else 0 end) as count_for_one,
sum(case when type = '2' then 1 else 0 end) as count_for_tow
FROM users
WHERE type IN ('1','2')
If you want separate numbers,
SELECT SUM(IF(type='1', 1, 0)), SUM(IF(type='2', 1, 0))
FROM users WHERE type IN ('1', '2')

a hard query to write in mysql to me?

field: content_id, value=1 or value=0, value_type=option
table: votingapi_vote
1,output the content_id field and descending it, the rule is according to the value(the count of each content_id 's value=1 minus the count of each content_id 's value=0 ,each content_id has many value=0 or value=1). where the value_type=option
is there a way to get that?
namely:
$query1=mysql_query(SELECT content_id, COUNT(*) FROM votingapi_vote WHERE value_type = option AND value = 1 GROUP BY content_id)
$query2=mysql_query(SELECT content_id, COUNT(*) FROM votingapi_vote WHERE value_type = option AND value = 0 GROUP BY content_id)
i want to use the count value = 1 minus the count value = 0. this is the content_id's descending rule,
For each content_id, the number of rows with value=1 minus the number of rows with value=0
SELECT content_id,
SUM(CASE WHEN value=1 THEN 1
WHEN value=0 THEN -1
ELSE 0
END) AS ContentSum
FROM votingapi_vote
WHERE value_type = 'option'
GROUP BY content_id
ORDER BY ContentSum DESC
SELECT content_id, SUM(CASE value WHEN 1 THEN 1 WHEN 0 THEN -1 ELSE 0 END) valuesum
FROM votingapi_vote
WHERE value_type = 'option'
GROUP BY content_id
ORDER BY valuesum DESC

Categories