Query for adding totals sum - mysql

Table1
ID, ANumber, Type, Amount, Date
1, 00010, 400, 10, 2016-11-16
2, 00011, 600, 20, 2016-11-12
3, 00012, 600, 10, 2016-11-13
4, 00013, 500, 30, 2016-11-17
5, 00014, 400, 40, 2016-11-19
Results:
400, 60
600, 30
500, 30
totals, 110
I want to add the totals. this is an existing table i can only SELECT.
This is my query. i don't know how to add the totals
SELECT Type, SUM(Amount)
FROM table1
GROUP BY Type

You are looking for with rollup:
select type, sum(amount)
from t
group by type with rollup;
Note: The final group will have NULL for the type rather than totals. You can use coalesce() to get whatever value you want.

You can always sum the initial values you returned in your initial query to generate a total:
SELECT SUM(sums.`sum`) AS 'total' FROM (SELECT SUM(`Amount`) AS 'sum' FROM `table1` GROUP BY `Type`) sums

Related

How to compare sum with the amount?

The table looks like this:
id, price, amount, transactionid
1, 5, 10, abc
2, 5, 10, abc
3, 20, 40, def
4, 20, 40, def
5, 15, 40, xyz
6, 20, 40, xyz
I want to compare the sum of the amounts with the amount and only select that are not equal.
Also in the example: 15 + 20 != 40
SELECT sum(price), transactionid FROM payment group by transactionid
Now I need the check with one of the amounts from a row and show only if is unequal.
Set the conditions in the HAVING clause:
SELECT transactionid,
SUM(price) total_price,
MAX(amount) amount
FROM payment
GROUP BY transactionid
HAVING total_price <> amount;
See the demo.

use group by max() twice in another column

I use mysql query.
I want to know the date and amount of the highest salary.
I want to know if I can use max() twice as below.
The result comes out exactly as I want.
But as far as I know, you have to use only one max().
Was I mistaken?
http://sqlfiddle.com/#!9/8db0c17/4
create table test ( mid bigint , sal bigint , dt date);
insert into test values( 1, 100, '2020-01-01 00:00:00'),
( 1, 200, '2020-02-01 00:00:00'),
( 2, 100, '2020-03-01 00:00:00'),
( 2, 200, '2020-04-01 00:00:00'),
( 2, 300, '2020-05-01 00:00:00'),
( 3, 500, '2020-10-01 00:00:00');
select mid, max(sal), max(dt) from test group by mid;
mid max(sal) max(dt)
1 200 2020-02-01
2 300 2020-05-01
3 500 2020-10-01
You can use max several times in your query, but in your case, you will not get what you want.
If we change your data like this:
1, 100, 2020-01-01
1, 200, 2020-02-01
2, 100, 2020-02-01
2, 300, 2020-03-01
2, 200, 2020-04-01
2, 300, 2020-05-01
3, 500, 2020-10-01
3, 300, 2020-11-01
Your result will be:
1, 200, 2020-02-01
2, 300, 2020-05-01
3, 500, 2020-11-01
As you can see, for 3rd row we get maximum value for sal and for dt but separately.
We can use somthing like this to get the right result:
select
t.mid, max(t.dt), tmp.sal_max
from test t
join (
select t1.mid, max(t1.sal) as sal_max
from test t1
group by t1.mid) tmp on tmp.mid = t.mid AND tmp.sal_max = t.sal
group by tmp.mid;
Result:
1, 2020-02-01, 200
2, 2020-05-01, 300
3, 2020-10-01, 500
I think it is not the simplest option, but it will work.
Yes you can use max many times it should be different columns names
The other column should be in group by

Get previous X days of revenue for each group

Here is my table
CREATE TABLE financials (
id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
CountryID VARCHAR(30) NOT NULL,
ProductID VARCHAR(30) NOT NULL,
Revenue INT NOT NULL,
cost INT NOT NULL,
reg_date TIMESTAMP
);
INSERT INTO `financials` (`id`, `CountryID`, `ProductID`, `Revenue`, `cost`, `reg_date`) VALUES
( 1, 'Canada', 'Doe' , 20, 5, '2010-01-31 12:01:01'),
( 2, 'USA' , 'Tyson' , 40, 15, '2010-02-14 12:01:01'),
( 3, 'France', 'Keaton', 80, 25, '2010-03-25 12:01:01'),
( 4, 'France', 'Keaton',180, 45, '2010-04-24 12:01:01'),
( 5, 'France', 'Keaton', 30, 6, '2010-04-25 12:01:01'),
( 6, 'France', 'Emma' , 15, 2, '2010-01-24 12:01:01'),
( 7, 'France', 'Emma' , 60, 36, '2010-01-25 12:01:01'),
( 8, 'France', 'Lammy' ,130, 26, '2010-04-25 12:01:01'),
( 9, 'France', 'Louis' ,350, 12, '2010-04-25 12:01:01'),
(10, 'France', 'Dennis',100,200, '2010-04-25 12:01:01'),
(11, 'USA' , 'Zooey' , 70, 16, '2010-04-25 12:01:01'),
(12, 'France', 'Alex' , 2, 16, '2010-04-25 12:01:01');
For each product and date combination, I need to get the revenue for previous 5 days. For instance, for Product ‘Keaton’, the last purchase was on 2010-04-25, it will only sum up revenue between 2010-04-20 to 2010-04-25 and therefore it will be 210. While for "Emma", it would return 75, since it would sum everything between 2010-01-20 to 2010-01-25.
SELECT ProductID, sum(revenue), reg_date
FROM financials f
Where reg_date in (
SELECT reg_date
FROM financials as t2
WHERE t2.ProductID = f.productID
ORDER BY reg_date
LIMIT 5)
Unfortunately, when i use either https://sqltest.net/ or http://sqlfiddle.com/ it says that 'LIMIT & IN/ALL/ANY/SOME subquery' is not supported. Would my query work or not?
Your query is on the right track, but probably won't work in MySQL. MySQL has limitations on the use of in and limit with subqueries.
Instead:
SELECT f.ProductID, SUM(f.revenue)
FROM financials f JOIN
(SELECT ProductId, MAX(reg_date) as max_reg_date
FROM financials
GROUP BY ProductId
) ff
ON f.ProductId = ff.ProductId and
f.reg_date >= ff.max_reg_date - interval 5 day
GROUP BY f.ProductId;
EDIT:
If you want this for each product and date combination, then you can use a self join or correlated subquery:
SELECT f.*,
(SELECT SUM(f2.revenue)
FROM financials f2
WHERE f2.ProductId = f.ProductId AND
f2.reg_date <= f.reg_date AND
f2.reg_date >= f.reg_date - interval 5 day
) as sum_five_preceding_days
FROM financials f;
After some trials I ended up with some complex query, that I think it solves your problem
SELECT
financials.ProductID, sum(financials.Revenue) as Revenues
FROM
financials
INNER JOIN (
SELECT ProductId, GROUP_CONCAT(id ORDER BY reg_date DESC) groupedIds
FROM financials
group by ProductId
) group_max
ON financials.ProductId = group_max.ProductId
AND FIND_IN_SET(financials.id, groupedIds) BETWEEN 1 AND 5
group by financials.ProductID
First I used group by financials.ProductID to count revenues by products. The real problem you are facing is eliminating all rows that are not in the top 5, for each group. For that I used the solution from this question, GROUP_CONCAT and FIND_IN_SET, to get the top 5 result without LIMIT. Instead of WHERE IN I used JOIN but with this, WHERE IN might also work.
Heres the FIDDLE

Can I transpose (Pivot) a table using a 'where' clause?

I need to create a pivot table from an original table in mysql, but I need to be specific about which rows i want to take the data into the new table i'm making.
I would be guessing i could use the 'where' clause in a query to create the pivot table, but i dont know exactly how. I have a code that allows me to create a pivot table from its original. It selects two rows, one for each 'max' function and turns them into columns.
create table `transp_table` as
select * from (
select original_table,
max(case when ID = 1.01 then value else 0 end) '1.01',
max(case when ID = 1.02 then value else 0 end) '1.02'
from(
select ID, `month_1` value, 1 descrip
from disp
union all
select ID, `month_2` value, 2 descrip
from disp
union all
select ID, `month_3` value, 3 descrip
from disp
union all
select ID, `month_4` value, 4 descrip
from disp
union all
select ID, `month_5` value, 5 descrip
from disp
union all
select ID, `month_6` value, 6 descrip
from disp
union all
select ID, `month_7` value, 7 descrip
from disp
union all
select ID, `month_8` value, 8 descrip
from original_table
) src
group by descrip
) as `transp_table`;
It works well to creating a pivot table, but for this model, i need to include a 'max' function for each specific ID. And from the original_table, there is a lot of rows. And there is, for an instance, a column in the original_table called 'type_of_product', and i need to select the rows that have a specific string in it. Is there a query were i could select the rows to make the pivot table without having to type for each one of them like in the example above? Here's the structure with a sample of the original_table:
CREATE TABLE original_table (
`ID` float not null, `type_of_product` text, `month_1` int,
`month_2` int, `month_3` int, `month_4` int, `month_5` int, `month_6` int)
INSERT INTO `original_table` (
ID, type_of_procduct, `month-1`, `month_2`, `month_3`, `month_4`, `month_5`, `month_6`)
VALUES
(1.01, 'TV', 50, 53, 20, 33, 134, 0),
(1.02, 'DVD', 36, 12, 5, 0, 0, 26),
(2.01, 'DVD', 11, 12, 30, 5, 22, 0),
(3.01, 'CD', 0, 0, 3, 1, 0, 19),
(3.02, 'TV', 3, 6, 0, 0, 10, 15),
(3.03, 'TV', 500, 20, 0, 0, 0, 1);

MYSQL query - getting totals by month

http://sqlfiddle.com/#!2/6a6b1
The scheme is given above.. all I want to do is get the results as the total of sales/month... the user will enter a start date and end date and I can generate (in PHP) all the month and years for those dates. For example, if I want to know the total number of "sales" for 12 months, I know I can run 12 individual queries with start and end dates, but I want to run only one query where the result will look like:
Month numofsale
January - 2
Feb-1
March - 23
Apr - 10
and so on...
or just a list of sales without the months, I can then pair it to the array of months generated in the PHP ...any ideas...
Edit/schema and data pasted from sqlfiddle.com:
CREATE TABLE IF NOT EXISTS `lead_activity2` (
`lead_activity_id` int(11) NOT NULL AUTO_INCREMENT,
`sp_id` int(11) NOT NULL,
`act_date` datetime NOT NULL,
`act_name` varchar(255) NOT NULL,
PRIMARY KEY (`lead_activity_id`),
KEY `act_date` (`act_date`),
KEY `act_name` (`act_name`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 ;
INSERT INTO `lead_activity2` (`lead_activity_id`, `sp_id`, `act_date`, `act_name`) VALUES
(1, 5, '2012-10-16 16:05:29', 'sale'),
(2, 5, '2012-10-16 16:05:29', 'search'),
(3, 5, '2012-10-16 16:05:29', 'sale'),
(4, 5, '2012-10-17 16:05:29', 'DNC'),
(5, 5, '2012-10-17 16:05:29', 'sale'),
(6, 5, '2012-09-16 16:05:30', 'SCB'),
(7, 5, '2012-09-16 16:05:30', 'sale'),
(8, 5, '2012-08-16 16:05:30', 'sale'),
(9, 5,'2012-08-16 16:05:30', 'sale'),
(10, 5, '2012-07-16 16:05:30', 'sale');
SELECT DATE_FORMAT(date, "%m-%Y") AS Month, SUM(numofsale)
FROM <table_name>
WHERE <where-cond>
GROUP BY DATE_FORMAT(date, "%m-%Y")
Check following in your fiddle demo it works for me (remove where clause for testing)
SELECT DATE_FORMAT(act_date, "%m-%Y") AS Month, COUNT(*)
FROM lead_activity2
WHERE <where-cond-here> AND act_name='sale'
GROUP BY DATE_FORMAT(act_date, "%m-%Y")
It returns following result
MONTH COUNT(*)
07-2012 1
08-2012 2
09-2012 1
10-2012 3
You can try query as given below
select SUM(`SP_ID`) AS `Total` , DATE_FORMAT(act_date, "%M") AS Month, Month(`ACT_DATE`) AS `Month_number` from `lead_activity2` WHERE `ACT_DATE` BETWEEN '2012-05-01' AND '2012-12-17' group by Month(`ACT_DATE`)
Here 2012-05-01 and 2012-12-17 are date input from form. and It will be return you the sum of sales for particular month if exist in database.
thanks
Try this query -
SELECT
MONTH(act_date) month, COUNT(*)
FROM
lead_activity2
WHERE
YEAR(act_date) = 2012 AND act_name = 'sale'
GROUP BY
month
Check WHERE condition if it is OK for you - act_name = 'sale'.
If you want to output month names, then use MONTHNAME() function instead of MONTH().
SELECT YEAR(act_date), MONTH(act_date), COUNT(*)
FROM lead_activity2
GROUP BY YEAR(act_date), MONTH(act_date)
For getting data by month or any other data based on column you have to add GROUP BY.
You can add many columns or calculated values to GROUP BY.
I assume that "num of sales" means count of rows.
Sometimes you might want the month names as Jan, Feb, Mar .... Dec possibly for a Chart likeFusionChart
SELECT DATE_FORMAT(date, "%M") AS Month, SUM(numofsale)
FROM <Table_name>
GROUP BY DATE_FORMAT(date, "%M")
Results would look like this on table
MONTH COUNT(*)
Jul 1
Aug 2
SEP 1
OCT 3