SQL SUM() All with check from other table - php

Table con_projects
mysql> SELECT * FROM con_projects;
+----+---------------+---------------------+--------+
| id | project_name | project_description | status |
+----+---------------+---------------------+--------+
| 1 | Project 1 | Description IS Here | 1 |
| 2 | Project 2 | Description IS Here | 0 |
| 3 | Project 3 | Description IS Here | 1 |
| 4 | Project 4 | Description IS Here | 0 |
| 5 | Project 5 | Description IS Here | 1 |
+----+---------------+---------------------+--------+
Here status 1=active and 0=inactive
mysql> SELECT * FROM con_transactions;
+------+------+---------------------+--------+
| t_id | p_id | date | amount |
+------+------+---------------------+--------+
| 10 | 1 | 2016-02-17 19:24:05 | 1800 |
| 12 | 2 | 2016-02-18 11:40:13 | 200 |
| 17 | 3 | 2016-02-18 11:42:04 | 100 |
| 19 | 4 | 2016-02-18 11:45:43 | 1 |
| 20 | 5 | 2016-02-18 11:45:54 | 999 |
| 21 | 1 | 2016-02-18 11:46:02 | 1500 |
| 41 | 2 | 2016-02-18 17:23:14 | 500 |
| 42 | 3 | 2016-02-18 17:23:14 | 500 |
| 43 | 4 | 2016-02-18 17:23:15 | 500 |
| 44 | 5 | 2016-02-18 17:23:16 | 500 |
| 45 | 1 | 2016-02-18 17:23:16 | 500 |
| 46 | 2 | 2016-02-18 17:23:16 | 500 |
| 47 | 3 | 2016-02-18 17:23:17 | 500 |
| 48 | 4 | 2016-02-18 17:23:17 | 500 |
| 49 | 5 | 2016-02-18 17:23:18 | 500 |
| 50 | 1 | 2016-02-18 17:25:54 | 1000 |
| 51 | 1 | 2016-02-18 17:26:22 | 3000 |
| 52 | 2 | 2016-02-18 17:48:59 | 10 |
| 53 | 1 | 2016-02-18 17:48:59 | 10 |
| 55 | 1 | 2016-02-19 10:20:12 | 1000 |
+------+------+---------------------+--------+
Now I want to SUM() all amount from con_trnsactions whose p_id from con_projects status = 1
I tried this and many more
mysql> SELECT (SELECT SUM(t.amount) FROM con_transactions t WHERE p.id=t.p_id) as total FROM con_projects p WHERE status='1'
+-------+
| total |
+-------+
| 14120 |
+-------+
AND
mysql> SELECT SUM(amount) from con_transactions;
+-------------+
| SUM(amount) |
+-------------+
| 14120 |
+-------------+
Both Are Same . But The subtraction will be like this.
mysql> SELECT 1800+100+999+1500+500+500+500+500+500+1000+3000+10+1000;
+---------------------------------------------------------+
| 1800+100+999+1500+500+500+500+500+500+1000+3000+10+1000 |
+---------------------------------------------------------+
| 11909 |
+---------------------------------------------------------+
here is the all active project (con_trsaction.p_id=con_projects.id AND con_projects.status=1) id (p_id) From con_trsanction.amount

Try this:
SELECT SUM(t.amount)
FROM con_transactions t
INNER JOIN con_projects AS p ON t.p_id = p.id
WHERE p.status = 1
It's a simple join operation. Only 'active' projects will be accounted for in the summation.

SELECT SUM(amount) from con_transactions LEFT JOIN con_projects ON con_projects.id = con_transactions.p_id WHERE con_projects.status = 1;

Related

using group by and max on columns remove repeat value just get Maximum id value

I have a table 'group_get_max' using group by and max on column and I want to remove repeat value just get Maximum id value, How can I do?
this is my table.
SELECT * FROM for_test.group_get_max;
output
+----+--------------+----------+-------+------+----------+-------------+
| Id | warehouse_id | goods_id | price | inc | quantity | operated_at |
+----+--------------+----------+-------+------+----------+-------------+
| 1 | 1 | 2 | 100 | 50 | 50 | 2020-03-21 |
| 2 | 1 | 2 | 100 | 50 | 150 | 2020-03-22 |
| 3 | 1 | 2 | 100 | 50 | 100 | 2020-03-21 |
| 4 | 1 | 2 | 100 | 50 | 150 | 2020-03-23 |
| 5 | 1 | 2 | 100 | 50 | 200 | 2020-03-23 |
| 6 | 1 | 3 | 100 | 100 | 100 | 2020-03-21 |
| 7 | 1 | 3 | 100 | 50 | 150 | 2020-03-22 |
| 8 | 1 | 3 | 100 | 50 | 200 | 2020-03-22 |
| 9 | 1 | 3 | 100 | 50 | 200 | 2020-03-23 |
| 10 | 1 | 3 | 100 | 50 | 250 | 2020-03-23 |
| 11 | 1 | 3 | 100 | 50 | 250 | 2020-03-21 |
| 12 | 1 | 2 | 100 | 50 | 200 | 2020-03-22 |
+----+--------------+----------+-------+------+----------+-------------+
The following is the query to use GROUP BY and MAX columns −
SELECT
group_get_max.goods_id, group_get_max.warehouse_id,
group_get_max.quantity,group_get_max.operated_at,group_get_max.id
FROM
group_get_max
INNER JOIN
(SELECT
group_get_max.warehouse_id,
group_get_max.goods_id,
MAX(group_get_max.operated_at) AS operated_at
FROM
group_get_max
WHERE
group_get_max.operated_at < '2020-03-23'
AND group_get_max.warehouse_id IN ('1' , '2', '3')
GROUP BY group_get_max.goods_id , group_get_max.warehouse_id) AS q
ON group_get_max.operated_at = q.operated_at
AND q.warehouse_id = group_get_max.warehouse_id
AND q.goods_id = group_get_max.goods_id
WHERE
group_get_max.warehouse_id IN ('1', '2','3')
After this query, I will get these data
+----------+--------------+----------+-------------+----+
| goods_id | warehouse_id | quantity | operated_at | id |
+----------+--------------+----------+-------------+----+
| 2 | 1 | 200 | 2020-03-22 | 12 |
| 2 | 1 | 150 | 2020-03-22 | 2 |
| 3 | 1 | 200 | 2020-03-22 | 8 |
| 3 | 1 | 150 | 2020-03-22 | 7 |
+----------+--------------+----------+-------------+----+
But I just want to get max id after group by.
+----------+--------------+----------+-------------+----+
| goods_id | warehouse_id | quantity | operated_at | id |
+----------+--------------+----------+-------------+----+
| 3 | 1 | 200 | 2020-03-22 | 8 |
| 2 | 1 | 200 | 2020-03-22 | 12 |
+----------+--------------+----------+-------------+----+
How can I do? I'm waiting online
Instead of a join use a correlated subquery in the WHERE clause:
SELECT g.* FROM group_get_max AS g
WHERE g.operated_at < '2020-03-23' AND g.warehouse_id IN ('1' , '2', '3')
AND g.Id = (
SELECT Id FROM group_get_max
WHERE warehouse_id = g.warehouse_id AND goods_id = g.goods_id
AND operated_at < '2020-03-23' AND warehouse_id IN ('1' , '2', '3')
ORDER BY operated_at DESC, quantity DESC
LIMIT 1
)
See the demo.
For MySql 8.0+ you can use row_number() window function:
SELECT
t.Id, t.warehouse_id, t.goods_id,
t.price, t.inc, t.quantity, t.operated_at
FROM (
SELECT *,
row_number() over (partition by warehouse_id, goods_id order by operated_at DESC, quantity DESC) rn
FROM group_get_max
WHERE operated_at < '2020-03-23' AND warehouse_id IN ('1' , '2', '3')
) AS t
WHERE t.rn = 1
See the demo.
Results:
| Id | warehouse_id | goods_id | price | inc | quantity | operated_at |
| --- | ------------ | -------- | ----- | --- | -------- | ------------ |
| 8 | 1 | 3 | 100 | 50 | 200 | 2020-03-22 |
| 12 | 1 | 2 | 100 | 50 | 200 | 2020-03-22 |

mysql find number of entry in a different status in descending order

I have a table like this
+----+--------+--------+
| id | ref_id | status |
+----+--------+--------+
| 1 | 3 | 1 |
| 2 | 4 | 0 |
| 4 | 6 | 0 |
| 6 | 8 | 1 |
| 8 | 10 | 0 |
| 10 | 12 | 1 |
| 12 | 14 | 1 |
| 14 | 16 | 0 |
| 16 | 18 | 0 |
| 18 | 20 | 0 |
+----+--------+--------+
I want to find the number of rows that has a status 0 in descending order continuously. In this Case number would be 3
+----+--------+--------+
| id | ref_id | status |
+----+--------+--------+
| 1 | 3 | 1 |
| 2 | 4 | 0 |
| 4 | 6 | 0 |
| 6 | 8 | 1 |
| 8 | 10 | 1 |
| 10 | 12 | 1 |
| 12 | 14 | 0 |
| 14 | 16 | 0 |
| 16 | 18 | 0 |
| 18 | 20 | 0 |
+----+--------+--------+
In this case it is four
+----+--------+--------+
| id | ref_id | status |
+----+--------+--------+
| 1 | 3 | 1 |
| 2 | 4 | 0 |
| 4 | 6 | 0 |
| 6 | 8 | 1 |
| 8 | 10 | 1 |
| 10 | 12 | 1 |
| 12 | 14 | 0 |
| 14 | 16 | 0 |
| 16 | 18 | 0 |
| 18 | 20 | 1 |
+----+--------+--------+
In this case it is 0
So far I tried is processing the rows descending and finding it through php condition . Is there any better way to do it ?
I used this code in codeigniter and get the result
$this->db->select('count(id) as number');
$this->db->from('tablename');
$this->db->where('id > (select max(id) FROM tablename where status = 1)',
NULL, FALSE);
In mysql
SELECT count(id) as number FROM tablename
WHERE id > (select max(id) FROM tablename where status = 1)

MySQL count rows with two duplicate column values

I would like to count rows with the same serv AND spec. The below query counts the rows correctly:
SELECT *, COUNT(*) AS c
FROM table1
GROUP BY serv, spec
But I would like the output displayed as such:
Original:
+-----+------+------+
| id | serv | spec |
| 500 | 1 | 4 |
| 501 | 5 | 1 |
| 502 | 1 | 4 |
| 503 | 1 | 5 |
| 504 | 5 | 6 |
| 505 | 2 | 4 |
| 506 | 5 | 1 |
| 507 | 2 | 4 |
| 508 | 4 | 3 |
| 509 | 2 | 4 |
+-----+------+------+
Desired output:
+-----+------+------+-------+
| id | serv | spec | count |
| 500 | 1 | 4 | 2 |
| 502 | 1 | 4 | 2 |
| 503 | 1 | 5 | 1 |
| 505 | 2 | 4 | 3 |
| 507 | 2 | 4 | 3 |
| 509 | 2 | 4 | 3 |
| 508 | 4 | 3 | 1 |
| 501 | 5 | 1 | 2 |
| 506 | 5 | 1 | 2 |
| 504 | 5 | 6 | 1 |
+-----+------+------+-------+
Since MySQL doesn't support window functions, you have do the counts in a subquery, and then join this subquery to the table:
SELECT t.id, t.serv, t.spec, c.cnt
FROM
table1 t INNER JOIN (
SELECT serv, spec, COUNT(*) as cnt
FROM table1
GROUP BY serv, spec
) c ON t.serv = c.serv AND t.spec=c.spec

Query MySQL To Show Counting from the table relation

i have 3 tables. 2 reference table and one table transactions.
Table puskesmas
mysql> select id,nama from puskesmas;
+----+----------------------+
| id | nama |
+----+----------------------+
| 1 | BAMBANGLIPURO |
| 2 | BANGUNTAPAN |
| 3 | BANTUL |
| 4 | DLINGO |
| 5 | IMOGIRI |
| 6 | JETIS |
| 7 | KASIHAN |
| 8 | KRETEK |
| 9 | PAJANGAN |
| 10 | PANDAK |
+----+----------------------+
Table poli
mysql> select * from poli;
+----+---------------+
| id | nama |
+----+---------------+
| 1 | BP |
| 2 | KIA |
| 3 | GIGI |
| 4 | JIWA |
+----+---------------+
Table loket
mysql> select pasien_id,poli_id,puskesmas_id from loket limit 10;
+-----------+---------+--------------+
| pasien_id | poli_id | puskesmas_id |
+-----------+---------+--------------+
| 1 | 1 | 1 |
| 5 | 2 | 2 |
| 1 | 1 | 3 |
| 9 | 3 | 4 |
| 1 | 3 | 5 |
| 5 | 2 | 1 |
| 1 | 1 | 3 |
| 8 | 1 | 2 |
| 10 | 3 | 6 |
| 5 | 2 | 5 |
+-----------+---------+--------------+
I want to show the total number (count) of visits to puskesmas table. then made field all_total
fter that I want to take patient visits where poli_id = 1 and used as a column bp. for other poly are the same as the
+----+----------------------+--------------+------+------+------+------+
| id | nama | All Total | BP | KIA | GIGI | JIWA |
+----+----------------------+--------------+------+------+------+------+
| 1 | BAMBANGLIPURO | 30 | 10 | 3 | 15 | 2 |
| 2 | BANGUNTAPAN | 35 | 20 | 4 | 11 | 0 |
| 3 | BANTUL | 15 | 10 | 0 | 5 | 0 |
| 4 | DLINGO | 12 | 10 | 1 | 1 | 0 |
| 5 | IMOGIRI | 10 | 5 | 2 | 1 | 2 |
| 6 | JETIS | 25 | 13 | 3 | 7 | 2 |
| 7 | KASIHAN | 20 | 10 | 10 | 0 | 0 |
| 8 | KRETEK | 23 | 20 | 1 | 1 | 1 |
| 9 | PAJANGAN | 10 | 5 | 1 | 3 | 1 |
| 10 | PANDAK | 0 | 0 | 0 | 0 | 0 |
+----+----------------------+--------------+------+------+------+------+
I've tried to make a query to display like this but it always fails to hold. Can anyone help to make such queries desired results
i have tried query like this :
select puskesmas_id,
sum(case when poli_id=1 then 1 else 0 end) bp,
sum(case when poli_id=5 then 0 else 1 end) gigi,
count(id) total
from loket
group by puskesmas_id
and result like this :
+--------------+------+------+-------+
| puskesmas_id | bp | gigi | total |
+--------------+------+------+-------+
| 1 | 97 | 126 | 143 |
| 6 | 74 | 185 | 210 |
| 8 | 131 | 179 | 190 |
| 7 | 90 | 92 | 98 |
| 2 | 33 | 39 | 54 |
| 4 | 158 | 248 | 263 |
| 3 | 66 | 68 | 72 |
+--------------+------+------+-------+
but puskesmas_id the value 0 does not perform data when querying

SELECT UPDATE with IF Statements in mysql

i have this table called chara:
+----------+------------+----------------+-------------+------------+----------+----------+--------------+--------------+-----------+-----------+
| chara_id | chara_name | chara_class_id | chara_level | chara_gold | chara_hp | chara_mp | chara_max_hp | chara_max_mp | chara_atk | chara_def |
+----------+------------+----------------+-------------+------------+----------+----------+--------------+--------------+-----------+-----------+
| 1 | LawrenceX | 1 | 1 | 0 | 11610 | 1000 | 0 | 0 | 7 | 3 |
| 2 | Testo | 3 | 1 | 0 | 11465 | 900 | 0 | 0 | 9 | 1 |
| 3 | Viscocent | 2 | 1 | 0 | 11570 | 1100 | 0 | 0 | 5 | 5 |
| 4 | Piatos | 1 | 1 | 0 | 12470 | 1000 | 0 | 0 | 7 | 3 |
| 5 | Hello | 1 | 1 | 0 | 12600 | 1000 | 0 | 0 | 2 | 8 |
| 6 | Sample | 3 | 1 | 0 | 12700 | 900 | 0 | 0 | 9 | 1 |
| 7 | tester | 2 | 1 | 0 | 12500 | 1100 | 0 | 0 | 5 | 5 |
| 8 | Sampuro | 0 | 1 | 0 | 11700 | 100 | 0 | 0 | 5 | 5 |
+----------+------------+----------------+-------------+------------+----------+----------+--------------+--------------+-----------+-----------+
I have this chara_base_stat table:
+--------------+----------------+------------------+---------------+---------------+----------------+----------------+
| base_stat_id | chara_class_id | chara_base_level | chara_base_hp | chara_base_mp | chara_base_atk | chara_base_def |
+--------------+----------------+------------------+---------------+---------------+----------------+----------------+
| 1 | 1 | 1 | 1000 | 1000 | 5 | 5 |
| 2 | 1 | 2 | 1100 | 1100 | 10 | 10 |
| 3 | 1 | 3 | 1200 | 1200 | 15 | 15 |
| 4 | 1 | 4 | 1300 | 1300 | 20 | 20 |
| 5 | 1 | 5 | 1400 | 1400 | 25 | 25 |
| 6 | 2 | 1 | 900 | 1100 | 7 | 3 |
| 7 | 2 | 2 | 1000 | 1200 | 14 | 6 |
| 8 | 2 | 3 | 1100 | 1300 | 21 | 9 |
| 9 | 2 | 4 | 1200 | 1400 | 28 | 12 |
| 10 | 2 | 5 | 1300 | 1500 | 35 | 19 |
| 11 | 3 | 1 | 1100 | 900 | 2 | 8 |
| 12 | 3 | 2 | 1200 | 1000 | 4 | 16 |
| 13 | 3 | 3 | 1300 | 1100 | 6 | 24 |
| 14 | 3 | 4 | 1400 | 1200 | 8 | 32 |
| 15 | 3 | 5 | 1500 | 1300 | 16 | 40 |
+--------------+----------------+------------------+---------------+---------------+----------------+----------------+
and i have this script that updates the values of hp for every minute(using cronjob here):
$sql = "UPDATE chara SET chara_hp = chara_hp +100";
$stmt = $db->prepare($sql);
$stmt->execute();
My Struggle:
how can i add +100 to the current value of chara_hp on chara table where the current chara_hp in the chara table does not exceed in the chara_base_hp from chara_base_stat table
basically all i want is to only regenerate those players hp if it there current hp is lesser than of there current chara_base_hp from chara_base_stat table
Note: the current chara_base_hp corresponds to the current level of the player and chara_class_id of the player.
so far i have this query here:
SELECT ch.chara_hp, bs.chara_base_hp FROM chara ch inner join chara_base_stat bs on(ch.chara_class_id = bs.chara_class_id and ch.chara_level = bs.chara_base_level)
that returns
+----------+---------------+
| chara_hp | chara_base_hp |
+----------+---------------+
| 13210 | 1000 |
| 14070 | 1000 |
| 14200 | 1000 |
| 13170 | 900 |
| 14100 | 900 |
| 13065 | 1100 |
| 14300 | 1100 |
+----------+---------------+
i want to do this in sql:
if(chara_hp < chara_base_hp){ update chara set chara_hp = chara_hp + 100 }
UPDATE
chara ch INNER JOIN chara_base_stat bs
ON ch.chara_class_id = bs.chara_class_id
AND ch.chara_level = bs.chara_base_level
SET
ch.chara_hp = LEAST(bs.chara_base_hp, ch.chara_hp + 100)
WHERE
ch.chara_hp < bs.chara_base_hp

Categories