I want to get the total maximum number of column CODE which the maximum is defined by the last five digits from mybarcode column.
mybarcode | code | judge | create_date |
-------------+------+--------+-------------+
M71X400001 | 7 | pass |
M71X400002 | 7 | pass |
M71X400005 | 7 | pass |
M71X400010 | 7 | pass |
M81X400001 | 8 | pass |
M81X400002 | 8 | pass |
M81X400007 | 8 | pass |
M91X400001 | 9 | pass |
M91X400003 | 9 | pass |
```
Example:
>The maximum value of 7 from CODE column is 10 ( from M71X4'00010')
>The maximum value of 8 from CODE column is 7 ( from M81X4'00007')
>The maximum value of 9 from CODE column is 3 ( from M91X4'00003')
The result should be 10+7+3=20.
And want display in the result table below.
```
SELECT DAY,
SUM(CASE WHEN judge = 'pass' then 1 else 0 end) pass,
SUM(CASE WHEN judge = 'fail' then 1 else 0 end) fail
**??? as number**
from MYTABLE
where MONTH(create_date) = '04' and YEAR(create_date) = '2019'
GROUP BY DAY
Result Table
day | pass | fail | number |
--------+------+--------+----------+
1 | 9 | 0 | 20 |
2 | 9 | 0 | ?? |
3 | 9 | 0 | ?? |
I think you need to do group by two times. Please try below code -
For MySQL -
SELECT
DAY,
SUM(pass),
SUM(fail),
SUM(max_barcode)
FROM (
SELECT
DAY,
SUM(CASE WHEN judge = 'pass' then 1 else 0 end) pass,
SUM(CASE WHEN judge = 'fail' then 1 else 0 end) fail,
Code,
CAST(MAX(SUBSTRING(mybarcode, 5)) AS SIGNED) AS max_barcode
FROM MYTABLE
WHERE MONTH(create_date) = '%s' and YEAR(create_date) = '%s'
GROUP BY DAY, Code
) AS CTE
GROUP BY DAY;
FOR MS SQL Server -
;WITH CTE AS (
SELECT
DAY,
SUM(CASE WHEN judge = 'pass' then 1 else 0 end) pass,
SUM(CASE WHEN judge = 'fail' then 1 else 0 end) fail,
Code,
max_barcode = cast(max(right(mybarcode, 5)) as int)
FROM MYTABLE
WHERE MONTH(create_date) = '%s' and YEAR(create_date) = '%s'
GROUP BY DAY, Code
)
SELECT
DAY,
SUM(pass),
SUM(fail),
SUM(max_barcode)
FROM CTE
GROUP BY DAY;
I'm trying to achieve yearly data as pivot, this is my query
SELECT
month(te.topup_date) as month,
sum(CASE WHEN year(te.topup_date) = '2015' THEN te.topup_amount+ tp.topup_amount END) as '2015',
sum(CASE WHEN year(te.topup_date) = '2016' THEN te.topup_amount+ tp.topup_amount END) as '2016'
from te_daily_topup as te
inner join tp_daily_topup as tp on year(te.topup_date) = year(tp.topup_date)
where year(te.topup_date) between '2015' and '2016'
group by year(te.topup_date), month(te.topup_date)
The result from the above query
month | 2015 | 2016
--------------------
1 | 123 |
2 | 2343 |
1 | |234
2 | |7667
The result I'm looking for is below:
month | 2015 | 2016
--------------------
1 | 123 | 234
2 | 2343 | 7667
help me to modify this query..
Just remove year() from the GROUP BY:
select month(te.topup_date) as month,
sum(case when year(te.topup_date) = 2015 then te.topup_amount + tp.topup_amount end) as `2015`,
sum(case when year(te.topup_date) = 2016 then te.topup_amount + tp.topup_amount end) as `2016`
from te_daily_topup te inner join
tp_daily_topup tp
on year(te.topup_date) = year(tp.topup_date)
where year(te.topup_date) between 2015 and 2016
group by month(te.topup_date);
Note: Do not use single quotes for integer constants nor for column aliases. Only use single quotes for string and date constants.
I have a database that looks like this SQL Fiddle: http://sqlfiddle.com/#!9/aa02e/1
CREATE TABLE Table1
(`Store` varchar(1), `Date` date, `Product` varchar(2), `Weekday` int, `Month` int, `Revenue` float)
;
INSERT INTO Table1
(`Store`, `Date`, `Product`, `Weekday`, `Month`, `Revenue`)
VALUES
('a', '20160101', 'aa', 5, 1, 1.5),
('a', '20160101', 'bb', 5, 1, 4),
('a', '20160101', 'cc', 5, 1, 3.5),
('a', '20160108', 'dd', 5, 1, 2.5),
('a', '20160108', 'ee', 5, 1, 5),
('b', '20160204', 'aa', 4, 2, 9.5),
('b', '20160204', 'bb', 4, 2, 4),
('b', '20160204', 'cc', 4, 2, 3),
('b', '20160211', 'dd', 4, 2, 1.5),
('b', '20160211', 'ee', 4, 2, 2.5)
;
SELECT * FROM table1;
+-------+------------+---------+---------+-------+---------+
| Store | Date | Product | Weekday | Month | Revenue |
+-------+------------+---------+---------+-------+---------+
| a | 2016-01-01 | aa | 5 | 1 | 1.5 |
| a | 2016-01-01 | bb | 5 | 1 | 4 |
| a | 2016-01-01 | cc | 5 | 1 | 3.5 |
| a | 2016-01-08 | dd | 5 | 1 | 2.5 |
| a | 2016-01-08 | ee | 5 | 1 | 5 |
| b | 2016-02-04 | aa | 4 | 2 | 9.5 |
| b | 2016-02-04 | bb | 4 | 2 | 4 |
| b | 2016-02-04 | cc | 4 | 2 | 3 |
| b | 2016-02-11 | dd | 4 | 2 | 1.5 |
| b | 2016-02-11 | ee | 4 | 2 | 2.5 |
+-------+------------+---------+---------+-------+---------+
It shows revenue data for stores incl. products, date and the respective day/month.
I want to select the following:
Store
Monthly revenue totals (i.e. what is the total revenue for store a in Jan?)
Weekday revenue averages (i.e. what is the avg revenue for store a on Thu?)
The first and second bullet are straightforward, but I'm having problems with the last one.
Currently, it takes the average over all products and all dates (assuming the weekday matches). What I need are the following steps:
Sum up all revenues for a store and a particular date (e.g. for store b: 9.5+4+3=16.5 for Feb 4th, and 1.5+2.5=4 for Feb 11th) if that date has the same weekday (here Thursday)
Take the average of the two values (e.g. avg(16.5,4)=10.25)
How can I accomplish that?
Thank you
Here is the query:
SELECT
Store,
SUM(CASE WHEN Month = 1 THEN Revenue ELSE NULL END) AS REVENUE_JAN,
SUM(CASE WHEN Month = 2 THEN Revenue ELSE NULL END) AS REVENUE_FEB,
AVG(CASE WHEN Weekday = 4 THEN Revenue ELSE NULL END) AS REVENUE_THU,
AVG(CASE WHEN Weekday = 5 THEN Revenue ELSE NULL END) AS REVENUE_FRI
FROM Table1
GROUP BY
Store
;
The weekday average is tricky. Your query is getting the average "order size" per weekday. But you want the total revenue.
One method is to first aggregate by weekday, but that is a bit of a mess. Instead, you can use this trick of calculating the average by dividing the total revenue by the number of days:
SELECT Store,
SUM(CASE WHEN Month = 1 THEN Revenue ELSE NULL END) AS REVENUE_JAN,
SUM(CASE WHEN Month = 2 THEN Revenue ELSE NULL END) AS REVENUE_FEB,
(SUM(CASE WHEN Weekday = 4 THEN Revenue END) /
COUNT(DISTINCT CASE WHEN Weekday = 4 THEN Date END)
) AS REVENUE_THU,
(SUM(CASE WHEN Weekday = 5 THEN Revenue END) /
COUNT(DISTINCT CASE WHEN Weekday = 5 THEN Date END)
) AS REVENUE_FRI
FROM Table1
GROUP BY Store;
SELECT
t1.store,
SUM(CASE WHEN Month = 1 THEN Revenue ELSE NULL END) AS REVENUE_JAN,
SUM(CASE WHEN Month = 2 THEN Revenue ELSE NULL END) AS REVENUE_FEB,
daily.REVENUE_THU,
daily.REVENUE_FRI
FROM Table1 t1
JOIN (
SELECT
Store,
weekday,
avg(CASE WHEN weekday = 4 THEN sum_rev END) as REVENUE_THU,
avg(CASE WHEN weekday = 5 THEN sum_rev END) as REVENUE_FRI
FROM (
SELECT
Store, date, weekday,
SUM(revenue) AS sum_rev
FROM Table1
GROUP BY
Store, date, weekday
) AS foo
GROUP BY Store, weekday
) AS daily ON daily.store = t1.store
GROUP BY
t1.store
How about this solution it return average for chosen day of chosen store
CREATE PROCEDURE sumForDayStore(IN vday INTEGER, IN vStore VARCHAR(50))
BEGIN
DECLARE totalDays INTEGER;
DECLARE totalRevenu INTEGER;
SET totalDays = (SELECT count(*) FROM Table1 WHERE WeekDay = vDay AND store = vStore);
SET totalRevenu = (SELECT sum(Revenue) FROM Table1 WHERE WeekDay = vDay AND store = vStore);
SELECT totalRevenu/totalDays;
END;
CALL sumForDayStore(5,'a');
How about this one:
SELECT mnth.Store, REVENUE_JAN, REVENUE_FEB, avg(rthu) REVENUE_THU, avg(rfri) REVENUE_FRI
FROM
(Select Store, sum(case when Month = 1 then Revenue else NULL END) REVENUE_JAN,
sum(case when Month = 2 then Revenue else NULL END) REVENUE_FEB
From Table1 group by Store) as mnth
join
(Select Store, sum(case when Weekday = 4 then Revenue end) rThu,
sum(case when Weekday = 5 then Revenue end) rFri from Table1 group by Store, Date) as dys
on mnth.Store = dys.Store
group by mnth.Store, REVENUE_JAN, REVENUE_FEB
I compared the performance of this with the query in the first answer and it shows better performance according to SQL server execution plan (1.6 times faster). Maybe this would be helpful on a larger data set.
I have a table 'QuarterlyReport' which has multiple company's quarterly profit figures with the following column 'CompanyName', 'QuarterEndDate' & 'Profit'
|CompanyName|QuarterEndDate|Profit|
|---------------------------------|
|A |2013-06-30 |29878 |
|A |2013-09-30 |33712 |
|A |2013-12-31 |60764 |
|A |2014-03-31 |260734|
|B |2013-06-30 |-1234 |
|B |2013-09-30 |0 |
|B |2013-12-31 |20114 |
|B |2014-03-31 |-984 |
...
I am trying to construct a MySQL query to see which company has a profit performance which increases in every consecutive quarters (Q4>Q3>Q2>Q1), with a 1 year (4 quarters) date range.
In the case of example above, only Company 'A' will meet this requirement and shall be return as the query's result
Currently I only able to construct query for (Q4>0 AND Q3>0 AND Q2>0) using follow MySQL query:
SELECT * FROM (SELECT q.CompanyName, q.QuarterEndDate, q.Profit FROM `QuarterlyReport` q) a
WHERE a.QuarterEndDate >= '2013-06-30' AND
a.QuarterEndDate < '2014-06-30' AND
a.CompanyName IN (SELECT CompanyName FROM `QuarterlyReport` WHERE
a.CompanyName IN (SELECT Q4.CompanyName FROM `QuarterlyReport` AS Q4 WHERE Q4.QuarterEndDate = '2014-03-31' AND Q4.Profit > '0') AND
a.CompanyName IN (SELECT Q3.CompanyName FROM `QuarterlyReport` AS Q3 WHERE Q3.QuarterEndDate = '2013-12-31' AND Q3.Profit > '0') AND
a.CompanyName IN (SELECT Q2.CompanyName FROM `QuarterlyReport` AS Q2 WHERE Q2.QuarterEndDate = '2013-09-30' AND Q2.Profit > '0') AND
a.CompanyName IN (SELECT Q1.CompanyName FROM `QuarterlyReport` AS Q1 WHERE Q1.QuarterEndDate = '2013-06-30' AND Q1.Profit > '0')
GROUP BY a.CompanyName ORDER BY a.CompanyName ASC
Can anyone suggest some idea on how to archive my targeted query?
You can do
SELECT *
FROM
(
SELECT CompanyName,
MAX(CASE WHEN QUARTER(QuarterEndDate) = 2 THEN Profit END) q1,
MAX(CASE WHEN QUARTER(QuarterEndDate) = 3 THEN Profit END) q2,
MAX(CASE WHEN QUARTER(QuarterEndDate) = 4 THEN Profit END) q3,
MAX(CASE WHEN QUARTER(QuarterEndDate) = 1 THEN Profit END) q4
FROM QuarterlyReport
WHERE QuarterEndDate >= '2013-06-30' AND QuarterEndDate < '2014-06-30'
GROUP BY CompanyName
) q
WHERE q1 < q2 AND q2 < q3 AND q3 < q4
Output:
| COMPANYNAME | Q1 | Q2 | Q3 | Q4 |
|-------------|-------|-------|-------|--------|
| A | 29878 | 33712 | 60764 | 260734 |
Here is SQLFiddle demo
Try:
select q.*
from quarterlyreport q
join
(
select companyname
from quarterlyreport
where quarterenddate between '2013-06-30' and '2014-06-30'
group by companyname
having sum(case when quarter(quarterenddate) = 1 then profit else 0 end)
> sum(case when quarter(quarterenddate) = 4 then profit else 0 end)
and sum(case when quarter(quarterenddate) = 4 then profit else 0 end)
> sum(case when quarter(quarterenddate) = 3 then profit else 0 end)
and sum(case when quarter(quarterenddate) = 3 then profit else 0 end)
> sum(case when quarter(quarterenddate) = 2 then profit else 0 end)
) v
on q.companyname = v.companyname
I am using this query for weekly reporting but can not found a way like this
week_number | week_startdate | organization_1 | organization_2
---------------------------------------------------------------
1 | 2013-01--05 |count(date) like 4,24,etc_ | count(date) like 4,24,etc_
SQL:
SELECT WEEK(signed_date) AS week_name, signed_date AS Week_Starting,
YEAR(signed_date), WEEK(signed_date), COUNT(*)
FROM business
WHERE YEAR(signed_date) = YEAR(CURDATE())
GROUP BY CONCAT(YEAR(signed_date), '/', WEEK(signed_date))
ORDER BY YEAR(signed_date), WEEK(signed_date
SAMPLE DATA:
signed_date | organization_id
01-01-2013 | 1
02-01-2013 | 1
03-01-2013 | 2
In 1 week organization_1 have 2 signed & organization_2 has 1 signed.
You should use case within count or sum:
SELECT WEEK(signed_date) AS week_name, signed_date AS Week_Starting,
YEAR(signed_date), WEEK(signed_date),
SUM(CASE WHEN organization_id=1 THEN 1 ELSE 0 END) as organization_1,
SUM(CASE WHEN organization_id=2 THEN 1 ELSE 0 END) as organization_2
FROM business
WHERE YEAR(signed_date) = YEAR(CURDATE())
GROUP BY CONCAT(YEAR(signed_date), '/', WEEK(signed_date))
ORDER BY YEAR(signed_date), WEEK(signed_date);
http://sqlfiddle.com/#!2/587ad/3