How to compare sum with the amount? - mysql

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.

Related

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

Cumulative sum with max date group by month year and id

Now i need to make similar query but need to several criteria
Here is my table
`transaksi` (`transid`, `idpinj`, `tanggal`,`sisapokok`, `sisajasa`
(1, 1, '2018-01-01', 1000, 100, 1),
(2, 1, '2018-01-05', 1000, 100, 3),
(3, 2, '2018-02-04', 1000, 100, 4),
(4, 2, '2018-02-08', 1000, 100, 5),
(5, 1, '2018-02-19', 1000, 100, 3),
(6, 3, '2018-02-22', 1000, 100, 2),
(7, 2, '2018-03-09', 1000, 100, 3),
(8, 3, '2018-03-10', 1000, 100, 3)
(9, 3, '2018-03-12', 1000, 100, 4)
(10, 1, '2018-03-17', 1000, 100, 4)
(11, 4, '2018-03-19', 1000, 100, 3)
(12, 2, '2018-03-20', 1000, 100, 4)
DB Fiddle table
From the table above i need to get output as follow
Month sisapokok sisajasa
Jan-2018 1000 100 ->row2
Feb-2018 4000 400 ->+ row3+5
Mar-2018 12000 1200 ->+ row9+10+11+12
First I need to get sum(sisapokok) and sum(sisajasa) for each idpinj where date is max(tanggal), status between 3 and 4. This value then sum as total per month
Make cumulative sum each month for the last 12 month
I try this query but it get the max(date) from all records not max(date) by month and each idpinj.
SELECT a.idpinj,a.sisapokok
FROM transaksi a
INNER JOIN
(
SELECT idpinj, MAX(tanggal) tgl
FROM transaksi
GROUP BY idpinj
) b ON a.idpinj = b.idpinj
AND a.tanggal = b.tgl
ORDER BY `a`.`idpinj` ASC
Not sure exactly what you are asking for but see if this helps:
select monthyear, sum(sisapokok)sisapokok, sum(sisajasa)sisajasa from (
select cast(month(tanggal) as varchar)+'-'+cast(year(tanggal) as varchar) monthyear, sum(sisapokok)sisapokok, sum(sisajasa)sisajasa
from #transaksi
group by cast(month(idpinj) as varchar)+'-'+cast(year(tanggal) as varchar) , tanggal) a
group by monthyear
Based on the fiddle data
select yyyy,mm,
#s:=#s+sisapokok sisapokok,
#t:=#t+sisajasa sisajasa
from
(
select yyyy,mm,sum(sisapokok) sisapokok,sum(sisajasa) sisajasa
from
(
select year(tanggal) yyyy,month(tanggal) mm, sisapokok,sisajasa
from transaksi t
join
(
select year(tanggal) yyyy,month(tanggal) mm,idpinj,max(transid) maxid
from `transaksi`
where status in(3,4)
group by year(tanggal),month(tanggal),idpinj
) s on s.maxid = transid
) t
group by yyyy,mm
) u
,(select #s:=0,#t:=0) r
order by yyyy,mm
+------+------+-----------+----------+
| yyyy | mm | sisapokok | sisajasa |
+------+------+-----------+----------+
| 2018 | 1 | 2000 | 2003 |
| 2018 | 2 | 5000 | 2303 |
| 2018 | 3 | 13000 | 3103 |
+------+------+-----------+----------+
3 rows in set (0.00 sec)
Note the inner query finds the last relevant id and the code progresses outward to use variables to calculate running totals.

MySQL: Aggregating counts

I'm trying to find how many companies had sales in a specific segment. I've managed to get a count of the sales entries (5), but I can't seem to aggregate by the product segment as well. Please see this simplification:
http://sqlfiddle.com/#!9/685cb/1
CREATE TABLE Table1
(`company` text, `sales` int, `segment` text)
;
INSERT INTO Table1
(`company`, `segment`, `sales`)
VALUES
('ACME',10,100),
('ACME',11,100),
('HAL',10,25),
('HAL',13,25),
('GEN',11,50)
;
SELECT COUNT(company) AS companies,
CASE
WHEN segment IN (10, 11, 12, 13, 14, 15, 16)
THEN 'Product segment A'
WHEN segment IN (20, 21, 22)
THEN 'Product segment B'
WHEN segment IN (30)
THEN 'Product segment C'
END AS grp, SUM(sales) AS sum_sales
FROM Table1
WHERE
(company LIKE '%ACME%'
OR company LIKE '%HAL%'
OR company LIKE '%GEN%'
)
AND
segment IN (10, 11, 12, 13, 14, 15 ,16, 20, 21, 22, 30)
GROUP BY grp
ORDER BY grp
;
The goal is to get "companies" to show 3, as there are three companies that had sales in segment A.
You could use the distinct modifier in the count function to get the number of different entries:
SELECT COUNT(DISTINCT company) AS companies,
-- Here -----^
CASE
WHEN segment IN (10, 11, 12, 13, 14, 15, 16)
THEN 'Product segment A'
WHEN segment IN (20, 21, 22)
THEN 'Product segment B'
WHEN segment IN (30)
THEN 'Product segment C'
END AS grp, SUM(sales) AS sum_sales
FROM Table1
WHERE
(company LIKE '%ACME%'
OR company LIKE '%HAL%'
OR company LIKE '%GEN%'
)
AND
segment IN (10, 11, 12, 13, 14, 15 ,16, 20, 21, 22, 30)
GROUP BY grp
ORDER BY grp
;
SQLFiddle

Query for adding totals sum

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

Mysql gaps and islands issue?

Would like to count number of rows between occurrence where total number of score is above 60, and count number of rows where this occurrence doesn't happened.
For example 5th and 6th game will end up with more then 60, so will count 5 rows with not 60 and 2 rows with 60.
I would like something like this:
type count
no-60-gap 5
yes-60-island 1
no-60-gap 3
yes-60-island 2
I have simple database of basketball games. Rough example below
id, home, score_home, away, score_away, round
1, team_1, 33, team_2, 23, 1
2, team_4, 31, team_1, 33, 1
3, team_2, 36, team_5, 53, 2
4, team_5, 35, team_1, 63, 2
5, team_7, 31, team_8, 53, 3
6, team_2, 30, team_1, 43, 3
7, team_1, 39, team_3, 13, 4
Was google-ing out this issues and I have end up trying to solve my problem with gaps and islands.
This is my solution but it not working. Idea was just to reset gap/island to 0 when it doesn't happened.
I am kind a new in this.
SET #gap :=0; SET #island :=0;
SELECT
#gap,
#island
FROM (
SELECT
CASE
WHEN (score_home + score_away) >= 60 THEN #island:=#island+1
WHEN (score_home + score_away) >= 60 THEN #gap:=0
END,
CASE
WHEN (score_home + score_away) < 60 THEN #island:=0
WHEN (score_home + score_away) < 60 THEN #gap:=#gap+1
END
FROM basket
) AS games
Appreciate any help
I suppose you're after something like this...
SELECT v,flag,COUNT(*)
FROM
( SELECT flag
, CASE WHEN #prev = flag THEN #v:=#v ELSE #v:=#v+1 END v
, #prev:=flag
FROM
( SELECT *, score_home + score_away >= 60 flag FROM my_table ) x
JOIN
( SELECT #prev:=NULL,#v:=0) vars
ORDER
BY id
) n
GROUP
BY v,flag;