specifying count with alias and group by month - php

SELECT MONTHNAME(date_added) as month,
(SELECT COUNT(*) FROM requests WHERE form_status = :approved) AS approved,
(SELECT COUNT(*) FROM requests WHERE form_status = :denied) AS denied,
(SELECT COUNT(*) FROM requests WHERE form_status = :completed) AS completed,
(SELECT COUNT(*) FROM requests WHERE form_status = :pending) AS pending
FROM requests WHERE req_dept = :req_dept GROUP BY month
the results isnt what i expected. I want to count form statuses and eventually group it by month but the result is it counts the same for every month. im using chartjs .

Lets Try this :-
WITH CTE AS (
SELECT MONTHNAME(DATE_ADDED) AS MONTH,
CASE WHEN FORM_STATUS = :APPROVED THEN 1 ELSE 0 END AS APPROVED,
CASE WHEN FORM_STATUS = :DENIED THEN 1 ELSE 0 END AS DENIED,
CASE WHEN FORM_STATUS = :COMPLETED THEN 1 ELSE 0 END AS COMPLETED,
CASE WHEN FORM_STATUS = :PENDING THEN 1 ELSE 0 END AS PENDING
FROM REQUESTS WHERE REQ_DEPT = :REQ_DEPT
) SELECT MONTH, SUM(APPROVED) AS APPROVED, SUM(DENIED) AS DENIED, SUM(COMPLETED) AS COMPLETED, SUM(PENDING) AS PENDING
GROUP BY MONTH

Related

Error on over() Clause for am calculate the rows based on id's to next or previous value in mysql

I am facing an issue where my query is not executing and I am getting the error near the over clause but I want result like see the pic below:
I mean I want result like 25000-9000 =16000 ;
16000-5000 =11000;
display output like that guys and here is my query
query:
SELECT s.id, s.cust_id,
s.package_name,s.pending_amount,s.pack_received_amount, s.return_amount,
s.payment_type,s.total_package_amount, SUM('s.pending_amount') OVER (ORDER
BY s.id ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW AS s.balance FROM
payment s WHERE s.cust_id = S1307 and s.package_name= switzerland
My error was here screen shot of images guys:
This is your query:
select . . .,
sum(s.pending_amount) over (order by s.id) as balance
from payment s
where s.cust_id = S1307 and s.package_name = 'switzerland';
If you don't have too many rows, a simple subquery will suffice:
select . . .,
(select sum(s2.pending_amount)
from payment s2
where s2.id <= s.id and
s2.cust_id = s.cust_id and
s2.package_name = s.package_name
) as balance
from payment s
where s.cust_id = 'S1307' and
s.package_name = 'switzerland';
SELECT Total,
Received,
CASE WHEN #balance = 0 THEN
(#balance := Total - Received)
ELSE
#balance := #balance - Received
END AS Balance
FROM
Table1,
(select #balance:=0) as t2
Table1
Total Received
-----------------
25000 9000
25000 5000
Output
Total Received Balance
----------------------------
25000 9000 16000
25000 5000 11000
DEMO
http://sqlfiddle.com/#!9/43cc31/18

MySQL - SELECT WHERE condition based on value of another SELECT

Hello I have two MySQL Querys where I am trying to use count and results from first select in condition for the second select.
Here is my code:
$sql = "SELECT m.name, m.id
FROM members m
WHERE m.online_status = 1 {$dep} ORDER BY m.name ASC";
$sql_second = "SELECT time_management.clientid, clients.client,
SUM( CASE WHEN MONTH(`date`) = 1 AND taskid <> 1 AND YEAR(date)='$year' THEN TIME_TO_SEC( `time` ) AND user = (result from previouse slect) ELSE 0 END) AS (user_1)
FROM time_management
LEFT JOIN clients ON time_management.clientid = clients.id
WHERE {$dep_where} = {$department_var}
GROUP BY clientid";
So first select is selecting all users which are unknown value. Name and ID
In the second query what I need is to Select for example:
let's say the first query returns
id:1 name: Jon
id:2 name: Mike
id:3 name: Dave
Total results: 3
so in this case in the second query the following line have to be repeaded 3 times for each user:
SUM( CASE WHEN MONTH(`date`) = 1 AND taskid <> 1 AND YEAR(date)='$year' THEN TIME_TO_SEC( `time` ) AND user = (result from previouse slect) ELSE 0 END) AS (user_1)
where user will be = to 1,2,3 for each line and (user_1) willbe (user_2), (user_3)
Is there a way this operation to be realized directly inside MySQL ? if now how it should be solved ?

Getting sorted mysql records with unique value

I'm trying to get some values from a database but limit it to 1 per account, and I'm having trouble getting it working how I want it.
Here is the query as it stands, which gets the emails in the correct order, and ignores the account:
SELECT ID FROM MailSent
WHERE DateSent IS NULL AND Valid = 1 ORDER BY Priority DESC LIMIT 14
I would like the highest priority record for each account (EmailID). I could just loop through the results and discard any duplicates, but then the actual limit would be a lot lower than the intended one.
Here's a few things I've tried:
SELECT ID, DISTINCT(EmailID) FROM MailSent
WHERE DateSent IS NULL AND Valid = 1 ORDER BY Priority DESC LIMIT 14
// error
SELECT DISTINCT(EmailID), ID FROM MailSent
WHERE DateSent IS NULL AND Valid = 1 ORDER BY Priority DESC LIMIT 14
// still has duplicates
SELECT ID FROM MailSent
WHERE DateSent IS NULL AND Valid = 1 ORDER BY Priority DESC GROUP BY EmailID LIMIT 14
// error
SELECT ID FROM MailSent
WHERE DateSent IS NULL AND Valid = 1 GROUP BY EmailID ORDER BY Priority DESC LIMIT 14
// wrong priority
As a bonus, but not required as it might be quite hard to do, it'd be nice having it limited to a user defined amount instead of just 1.
Just use variables
SELECT ID, EmaailID
FROM (
SELECT ID, EmailID,
#rn := if(#email = EmailID,
#rn + 1,
if(#email := EmailID, 1, 1)
) as rn
FROM MailSent
CROSS JOIN (SELECT #email := 0, #rn := 0) as param
WHERE DateSent IS NULL AND Valid = 1
ORDER BY Priority Desc
) T
WHERE T.rn = 1
Now if you want limit result for user, you need a settings table or a query from somewhere. Just replace previous WHERE for:
JOIN (SELECT userID, numberofRows
FROM SettingTable) P
ON T.ID = P.userID
AND T.rn <= P.numberofRows

Set status value with group by on different values with SQL

I have this SQL query
SELECT SUM(reach) AS reach, SUM(impressions) AS impressions, cpc, id_name,
SUM(clicks) AS clicks, SUM(amount_spent) AS amount, pagename, status
FROM mbk_ad_data
WHERE id_campaign_shortname = 'name'
AND adset_name NOT LIKE '%MSN%'
AND date_from = '2016-02-02'
AND date_to = '2016-02-09'
GROUP BY id_name
That will group and output this:
reach impressions cpc id_name clicks amount pagename status
4099 4529 6.34875 name 29 246.11 Name paused
This works almost as intended. I have two different rows with "pagename" Name and the summed up values are correct, but row 1 has status "active" and row 2 has status "paused". What I want is to have a status "active" in the output, if one of the rows has a status "active", so my output will be:
reach impressions cpc id_name clicks amount pagename status
4099 4529 6.34875 name 29 246.11 Name active
How can do this in the query?
Apply MIN on status:
SELECT SUM(reach) AS reach, SUM(impressions) AS impressions, cpc, id_name,
SUM(clicks) AS clicks, SUM(amount_spent) AS amount, pagename,
MIN(status) AS status
FROM mbk_ad_data
WHERE id_campaign_shortname = 'name'
AND adset_name NOT LIKE '%MSN%'
AND date_from = '2016-02-02'
AND date_to = '2016-02-09'
GROUP BY id_name
This way status = 'active' will take precedence over status = 'paused'. This will work as long as the group contains just these two values for status field.
You should get into the habit of including all non-aggregated columns in the GROUP BY.
Then, the rest can be done using aggregation:
SELECT SUM(reach) AS reach, SUM(impressions) AS impressions, cpc, id_name,
SUM(clicks) AS clicks, SUM(amount_spent) AS amount, pagename,
(CASE WHEN MAX(status = 'active') > 0 THEN 'active'
ELSE MAX(status)
END) as status
FROM mbk_ad_data
WHERE id_campaign_shortname = 'name' AND adset_name NOT LIKE '%MSN%' AND
date_from = '2016-02-02' AND date_to = '2016-02-09'
GROUP BY id_name, cpc, id_name, pagename;
Although there might be a very slight performance hit for including all the columns, including all the columns more than makes up for that problem by (1) being standard SQL and (2) by preventing unintentional errors.

Group sql query

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 :)

Categories