Mysql Nested query and GROUP BY - mysql

I am trying to perform the following query on my database :-
SELECT
source, Month as t1,
GROUP_CONCAT(SELECT SUM(amount) FROM `reports` GROUP BY Month) as amount
FROM `reports`
GROUP BY source
To get the source, month and the concatenated string of the sum of the money that is obtained by the distinct source in 1 month. But I get a syntax error.

I'm not exactly sure what you need, hopefully it is one of these two:
SELECT source, Month, SUM(amount) as sum
FROM reports
GROUP BY source, Month
The above, but grouped by source with the sums listed in one field:
SELECT source, GROUP_CONCAT(sum) as sums
FROM (
SELECT source, Month, SUM(amount) as sum
FROM reports
GROUP BY source, Month
) as t
GROUP BY source

Related

How to count total row on MySQL based upon month and year

My database table contains value in this way
IMAGE FOR TABLE DATA
I want to track down same email which has been used more than one times for a particular month and year.
In the above scenario, email that has been repeated multiple times was sandeshphuya#gmail.com, jes#gmail.com and ramu#gmail.com for different months. I want to track down customer repetition following their email for each month and year.
The query that I am using right now is
SELECT DATE_FORMAT(booked_on, '%Y-%m') as monthYear, email,
COUNT(*) AS 'Count'
FROM 'tablename'
GROUP BY email,DATE_FORMAT(booked_on, '%Y-%m') HAVING COUNT(*) > 1 ORDER BY `booked_on`;
GROUP BY email was used as it generates the repeated email and GROUP BY DATE_FORMAT(booked_on, '%Y'-%m') was used to track down total email repeated for each month/year.
This prints out data as
IMAGE FOR SELECT QUERY
How can I track down total repeated email following month and year? The expected result is
RESULT EXPECTED
You can use your query as a subquery for a new group by:
select sub.monthYear,count(*)
from
(SELECT DATE_FORMAT(booked_on, '%Y-%m') as monthYear,
email,
COUNT(*) AS 'Count'
FROM 'tablename'
GROUP BY email,DATE_FORMAT(booked_on, '%Y-%m')
HAVING COUNT(*) > 1
ORDER BY `booked_on`) as sub
GROUP BY sub.monthYear

Select query with calculated field that uses subquery with multiple conditions

Three Tables:
COST_SAVINGS: COST_SAVINGS_ID, ONE_TIME_CREDIT, CREATION_DATE, INVOICE_ID (FK to Invoice table)
INVOICE: INVOICE_ID, INVOICE_CURRENCY_CODE
EXCHANGE_RATE: CURRENCY_RATE, CURRENCY_DATE
I'm reporting on Cost Savings (the first table). The challenge is that each cost savings amount can be in a different currency so I need a field that shows the converted amount based on the currency from the invoice table and a matching month / year between the Exchange.Ex_Date and Cost_Savings.Create_Date.
I'm getting an error that states:
single-row subquery returns more than one row
This is what I have so far:
SELECT
COST_SAVINGS.COST_SAVINGS_ID,
COST_SAVINGS.CLAIM_TYPE,
COST_SAVINGS.COMMENTS,
COST_SAVINGS.COST_SAVINGS_STATUS,
COST_SAVINGS.CREATION_DATE,
COST_SAVINGS.DESCRIPTION,
COST_SAVINGS.ONE_TIME_CREDIT AS CREDIT_IN_NATIVE_CURRENCY,
FINANCE_INVOICE.CURRENCY_CODE,
COST_SAVINGS.ONE_TIME_CREDIT *
(SELECT EXCHANGE_RATE.CURRENCY_RATE
FROM EXCHANGE_RATE
WHERE EXTRACT (MONTH FROM COST_SAVINGS.CREATION_DATE) = EXTRACT (MONTH FROM EXCHANGE_RATE.CURRENCY_DATE)
AND EXTRACT (YEAR FROM COST_SAVINGS.CREATION_DATE) = EXTRACT (YEAR FROM EXCHANGE_RATE.CURRENCY_DATE)
AND FINANCE_INVOICE.CURRENCY_CODE = EXCHANGE_RATE.CURRENCY_CODE) AS CREDIT_IN_USD
FROM COST_SAVINGS
LEFT JOIN FINANCE_INVOICE ON COST_SAVINGS.INVOICE_ID = FINANCE_INVOICE.INVOICE_ID
I feel like the issue may be with the third WHERE clause in my subquery (Trying to match the Currency codes). I'm not sure how resolve it though. Any thoughts?
Try putting LIMIT 1 in your subquery:
...RENCY_CODE = EXCHANGE_RATE.CURRENCY_CODE LIMIT 1) AS CREDIT_IN_USD
I believe your subquery is returning multiple rows. That doesn't work when you use a subquery in place of a column name in your SELECT clause.
If you don't want to use a subquery in place of a column name, try something like this. You'll join to a subquery generated virtual table.
Here's the virtual table for exchange rates. It uses GROUP BY to make one row (or no rows per month/year/currency code. If more than one row is in the raw table for any month/year/code, they get averaged with AVG(). You could also use MAX() or MIN().
SELECT AVG(CURRENCY_RATE) CURRENCY_RATE,
CURRENCY_CODE,
EXTRACT(MONTH FROM CURRENCY_DATE) MONTH,
EXTRACT(YEAR FROM CURRENCY_DATE) YEAR
FROM EXCHANGE_RATE
GROUP BY CURRENCY_CODE,
EXTRACT(MONTH FROM CURRENCY_DATE),
EXTRACT(YEAR FROM CURRENCY_DATE)
Try this and convince yourself it works.
Then build it into your overall query.
SELECT
COST_SAVINGS.COST_SAVINGS_ID,
COST_SAVINGS.whatever, ...
FINANCE_INVOICE.CURRENCY_CODE,
(COST_SAVINGS.ONE_TIME_CREDIT * RATE.CURRENCY_RATE) AS CREDIT_IN_USD
FROM COST_SAVINGS
LEFT JOIN FINANCE_INVOICE ON COST_SAVINGS.INVOICE_ID = FINANCE_INVOICE.INVOICE_ID
LEFT JOIN (SELECT AVG(CURRENCY_RATE) CURRENCY_RATE,
CURRENCY_CODE,
EXTRACT(MONTH FROM CURRENCY_DATE) MONTH,
EXTRACT(YEAR FROM CURRENCY_DATE) YEAR
FROM EXCHANGE_RATE
GROUP BY CURRENCY_CODE,
EXTRACT(MONTH FROM CURRENCY_DATE),
EXTRACT(YEAR FROM CURRENCY_DATE)
) RATE ON RATE.CURRENCY_CODE = FINANCE_INVOICE.CURRENCY_CODE
AND RATE.YEAR = EXTRACT(YEAR FROM COST_SAVINGS.CREATION_DATE)
AND RATE.MONTH = EXTRACT(MONTH FROM COST_SAVINGS.CREATION_DATE)

related to query using SQL

In oracle sql, how to get the count of newly added customers only for the month of april and may and make sure they werent there in the previous months
SELECT CUSTOMER ID , COUNT(*)
FROM TABLE
WHERE DATE BETWEEN '1-APR-2018' AND '31-MAY-2018' AND ...
If we give max (date) and min(date), we can compare the greater date to check if this customer is new , correct?
expected output is month count
april ---
may ---
should show the exact count how many new customers joined in these two months
One approach is to use aggregation:
select customer_id, min(date) as min_date
from t
group by customer_id
having min(date) >= date '2018-04-01 and
min(date) < date '2018-06-01';
This gets the list of customers (which your query seems to be doing). To get the count, just use count(*) and make this a subquery.

Mysql Select group by and without group by in one query

How can I select group by and without group by in one select query? I have a query like this
SELECT date, sum(total) as quotation_total
FROM suspended_bills
WHERE type='quotation'
GROUP BY YEAR(date), MONTH(date)
Here it is taking a group by year and month but I want a sum(total) without group by year and month. So I am able to get full sum(total) without a division of month and year.
This is not a duplicate entry as rollup is generating extra rows that I dont need, I only need the total of sum, so when I run this query with rollup it gave me more rows that is not desired. So all is wrong with roll up query.
In MySQL, the easiest way is a join or subquery:
select YEAR(sb.date), MONTH(sb.date), sum(sb.total) as quotation_total,
t.total_total
from suspended_bills sb cross join
(select sum(total) as total_totla
from suspended_bills
where type = 'quotation'
) t
where sb.type = 'quotation'
group by YEAR(sb.date), MONTH(sb.date), t.total_total;

MySql, SELECT list is not in GROUP BY clause and contains nonaggregated column

I'm using MySql 5.7, and I'm getting an error in this query:
SELECT
COUNT(id) AS sales,
SUM(amount) AS total,
created
FROM
`payments`
WHERE status =1
GROUP BY MONTH(created);
if I change GROUP BY MONTH(created)
with:
GROUP BY created
then the error is gone. I dont have access to my.ini, to make changes to sql_mode.
Since you group month-wise, you shold output the months also
SELECT COUNT(id) AS sales,
SUM(amount) AS total,
MONTH(created)
FROM payments
WHERE status = 1
GROUP BY MONTH(created)
Otherwise MySQL has to pick a created value from the group. But you should define what to display.
Another possibility instead of outputting MONTH(created) would be a aggreagtion of the date like min(created) which would output the earliest date of each month.