MYSQL Query for Grouping Column Based on Different Conditions - mysql

I have project table in following format:
And, I need to have MYSQL that can give me data in following format:
Basically, I have to group the data based on location. Then have to count the successful and unsuccessful projects. "Successful" column has total count of projects for which percentageRaised is more than or equal to 1 and Unsuccessful column has total count of project for which percetageRaised in less than 1.
I just have basic understanding of mysql. Need your advise.

select location
, sum(case when PercentageRaised >= 1.0 then 1 end) as successful
, sum(case when PercentageRaised < 1.0 then 1 end) as unsuccessful
from YourTable
group by
location

MySQL Supports boolean arithmetic.
SELECT Location,
SUM(percentageRaised > 0) successful,
SUM(percentageRaised < 0) unsuccessful,
FROM tableName
GROUP BY Location

Related

COUNT() domain names in emails based on the current month returning all records

I have a query as such
SELECT right(accounts.username, length(accounts.username)-
INSTR(accounts.username, '#')) domain,
COUNT(*) email_count
FROM tickets
LEFT JOIN accounts ON tickets.user = accounts.ID
WHERE (tickets.timestamp >= UNIX_TIMESTAMP(MONTH(CURRENT_DATE())))
GROUP BY domain
ORDER BY email_count DESC
I have a ticket table that I LEFT JOIN to associate the user accounts of that ticket to get the email(username) of that user.
I am trying to count the users email and how many tickets appear with a particular domain name of that user for the current MONTH. Problem is that it is ignoring the MONTH and returning all records that match.
For instance
yahoo.com 3,356
gmail.com 1,345
If I do a search for all records I get these numbers, but it should be much lower if it is just for the month. I am using UNIX timestamps for this.
Can anyone help me?
If you consider the UNIX_TIMESTAMP(MONTH(CURRENT_DATE()))) expression:
MONTH(CURRENT_DATE()) => 1
UNIX_TIMESTAMP(1) => this should result either in an error (1292 incorrect datetime value) or warning of the same and 0 as a result, depending on whether strict sql mode is enabled.
Since you wrote the query returns all records, strict sql mode must be turned off, which can cause issues like this. It would have been easier to get a straight error message.
If you want to return records from the current month, then you can use the following expression, where I used year() and month() functions to get current year and month and concatenated 1 to it to get the 1st day of the month:
tickets.timestamp >= UNIX_TIMESTAMP(CONCAT(YEAR(CURRENT_DATE()),'-',MONTH(CURRENT_DATE()),'-','1')
WHERE tickets.timestamp >= UNIX_TIMESTAMP(MONTH(CURRENT_DATE()))
This expression probably does not do what you think. MONTH() returns the number of the month (1 to 12), while you want the beginning of the current month.
You can use the following expression to compute the beginning of the month:
date_format(current_date(), '%Y-%m-01')
In your condition:
where tickets.timestamp >= unix_timestamp(date_format(current_date(), '%Y-%m-01'))
Modified for only current month:
SELECT
RIGHT(accounts.username, length(accounts.username)-INSTR(accounts.username, '#')) AS domain, COUNT(1) AS email_count
FROM tickets
LEFT JOIN accounts ON tickets.user = accounts.ID
WHERE
YEAR(tickets.timestamp) = YEAR(NOW())
AND MONTH(tickets.timestamp) = MONTH(NOW())
GROUP BY domain
ORDER BY email_count DESC

Sum of multiple rows using different cases

In my table for payment details of a shop.Here Payment is done by using credit,debit and by cash.This will represent in the table like a field "mode"
If mode=1 cash,mode=2 credit and mode=3 debit.
Now i take the daily fee details using this query
SELECT * FROM (`fee_data`) WHERE `paid_date` = '2015-20-11'
I want to get the sum of Paid amount in different modes
How can i do this..
You can try this:
SET #paid_date = '2015-01-19 00:00:00';
SELECT
SUM (CASE WHEN MODE = 1 THEN VALUE_PAYMENT ELSE 0 END) TOTAL_1,
SUM (CASE WHEN MODE = 2 THEN VALUE_PAYMENT ELSE 0 END) TOTAL_2,
SUM (CASE WHEN MODE = 3 THEN VALUE_PAYMENT ELSE 0 END) TOTAL_3
FROM (`fee_data`) WHERE `paid_date` = #paid_date;
Where value_payment is the column you store the amount paid.
You can use sum(if( in combination with grouping by date, something like this:
SELECT `paid_date`, sum(if(mode=1, `fee_data`, 0)) sumMode1,
sum(if(mode=2, `fee_data`, 0)) sumMode2,
sum(if(mode=2, `fee_data`, 0)) sumMode3
FROM (`fee_data`) group by `paid_date`
With that you will get per date one line, where you have 3 aggregated columns. For each mode you have one aggregated field. Is that what you are looking for?
Try this :
SELECT * FROM (`fee_data`) WHERE `paid_date` = '2015-20-11' AND ModeID=1
make changes in DB tables accordingly
SELECT *, SUM(paid_amount) as sum_amount FROM (fee_data) WHERE paid_date = '2015-20-11' GROUP BY mode
I think this should work

How to select based on different column data

I want to perform a different SELECT based on the column data. For example I have a table http://sqlfiddle.com/#!2/093a2 where I want compare start_date and end_date only if use_schedule = 1. Otherwise select all data. (A different select) Basically I only want to compare the start and end date if only use_schedule is 1 and if use_schedule is 0 then select rest of the data.
An example may be something like
select id, name from table
where use_schedule = 0
else
select id, name, start_date from table
where use_schedule = 0 and current_date >= start_date.
Basically I have the data where schedule is enabled only then look into start and end date. Because if schedule is not enabled there is no point of looking into the dates. Just select the data. With schedule enabled, I want to be more selective in selecting the scheduled data.
I am trying to figure out if MySQL CASE or IF statements would work but not able to do so. How can I run this select?
Thanks.
You can use UNION to mix and match the results of 2 different SQL queries into one result set:
select id, name, null from table
where use_schedule = 0
union
select id, name, start_date from table
where use_schedule = 1 and current_date >= start_date
Note that both queries have to have compatible output fields (same number and type for this to work). The use of UNION automatically merges only distinct records - if you want to keep double results use UNION ALL instead.
In this specific case a more extensive WHERE-clause would also work obviously:
where use_schedule = 0 or (use_schedule = 1 and current_date >= start_date)
But given the question I'm assuming your real case is a bit more complex.
Documentation over at MySQL site.
Use CASE, in this case..:
SELECT id, name,
(CASE
WHEN start_date >= DATE(NOW()) AND use_schedule = 1
THEN start_date
ELSE NULL
END) AS cols FROM campaigns
This way it selects only the schedule 0 OR the 1 with a date bigger or equals to now;
I used DATE(NOW()) so that it removes the time which you are not interested in.

MySQL Query to perform calculation and display data based on 2 different date criteria

Good morning,
I am trying to combine two queries into one so that the result array can be populated into a single table. Data is pulled from a single table, and math calculations must take place for one of the columns. Here is what I have currently:
SELECT
laboratory,
SUM(total_produced_week) AS total_produced_sum,
SUM(total_produced_over14) AS total_over14_sum,
100*(SUM(total_produced_over14)/sum(total_produced_week)) as divided_sum,
max(case when metrics_date =maxdate then total_backlog else null end) as total_backlog,
max(case when metrics_date =maxdate then days_workable else null end) as days_workable,
max(case when metrics_date =maxdate then workable_backlog else null end) as workable_backlog,
max(case when metrics_date =maxdate then deferred_over_30_days else null end) as deferred_over_30_days
FROM
test,
(
select max(metrics_date) as maxdate
from metrics
) as x
WHERE
YEAR(metrics_date) = YEAR(CURDATE())
AND MONTH(metrics_date) = MONTH(CURDATE())
GROUP BY
laboratory
ORDER BY 1 ASC
Here's the breakdown:
For each laboratory site, I need:
1) Perform a MONTH TO DATE (current month only) sum, division and multiply by 100 for each site to obtain percentage.
2) Display other columns (total_backlog, days_workable, workable_backlog, deferred_over_30_days) for the most recent update date (metrics_date) only.
The above query performs #1 just fine - I get a total_produced_sum, total_over14_sum and divided_sum column with correct math.
The other columns mentioned in #2, however, return NULL. Data is available in the table for the most recently updated date, so the columns should be reporting that data. It seems like I have a problem with the CASE, but I'm not very familiar with the function so it could be incorrect.
I am running MySQL 5.0.45
Thanks in advance for any suggestions!
Chris
P.S. Here are the two original queries that work correctly. These need to be combined so that the full resultset can be output to a table, organized by laboratory.
Query 1:
SELECT SUM(total_produced_week) AS total_produced_sum,
SUM(total_produced_over14) AS total_over14_sum
FROM test
WHERE laboratory = 'Site1'
AND YEAR(metrics_date) = YEAR(CURDATE()) AND MONTH(metrics_date) = MONTH(CURDATE())
Query 2:
SELECT laboratory, total_backlog, days_workable, workable_backlog, deferred_over_30_days,
items_over_10_days, open_ncs, total_produced_week, total_produced_over14
FROM metrics
WHERE metrics_date = (select MAX(metrics_date) FROM metrics)
ORDER BY laboratory ASC
Operator Error.
I created a copy of the original table (named "metrics") to a table named "test". I then modified the metrics_date in the new "test" table to include data from January 2011 (for the month-to-date). While the first part of the query that performs the math was using the "test" table (and working properly), the second half that pulls the most-recently-updated data was using the original "metrics" table, which did not have any rows with a metrics_date this month.
When I changed the query to use "test" for both parts of the query, everything works as expected. And now I feel really dumb.
Thanks anyway, guys!

Count changes of a value over time?

again I am stuck with counting something in MySQL. The database structure is far from SOers´d call optimal, but nevertheless I do not have an influence here and have to live with it. Probably that´s one of the reasons why I need help again to get some information out of it :)
Assume I have:
some_id (not the PK of the table, not unique),
year, month (no date fields just two integer fields),
some_flag (character that is either A or B) .
Now I´d like to know how often some_flag has changed (in a given time span). The time span is not utterly important in the first approach, I just need to know how many changes happened. Note that changes can only happen monthly. My query:
SELECT some_id,year,some_flag FROM mytable
WHERE some_flag = "A" OR someflag = "B"
AND year > 2005
GROUP BY some_id,some_flag
HAVING COUNT(DISTINCT some_flag) > 1
returns an empty result set. What´s wrong with it? I am sure there are years in which the flag changes over months...
Isn't something like
select .... , sum(case when month=month-1 and some_flag != some_flag then 1 else 0 end) as changecount
possible ?
Try this:
SELECT some_flag, COUNT(some_id) FROM mytable
WHERE some_flag = "A" OR someflag = "B"
AND year > 2005
GROUP BY some_flag
HAVING COUNT(some_id) > 1
-Edit-
If you want to see a month over month count, try this:
(Note: it will only show months where it has changed)
SELECT some_flag, year, month, COUNT(some_id) FROM mytable
WHERE some_flag = "A" OR someflag = "B"
AND year > 2005
GROUP BY some_flag, month, year
HAVING COUNT(some_id) > 1
It looks to me like you need to do this in two parts.
First, execute this SQL query to get all of the values for some_id, some_flag:
SELECT some_id, some_flag, year, month
FROM ...
WHERE year > 2005
ORDER BY some_id, some_flag, year, month
Then, run the output through a match / merge process to detect when some_flag changes for a given some_id. Save the year and month that some_flag changes for reporting in the match / merge process.
When grouping by some_flag you're making COUNT(DISTINCT some_flag) to be always 1.
Try gouping only by some_id. I hope this helps.