mysql subquery count where and group by - php

I have 4 tables like
cc_agents
+----+----------+
| id | username |
+----+----------+
| 1 | sankar |
| 2 | jenifer |
| 3 | andrew |
| 4 | nirmal |
| 5 | raja |
+----+----------+
cc_callers
+----+-----------+
| id | name |
+----+-----------+
| 1 | sankar |
| 2 | nirmal |
| 3 | jenifer |
| 4 | raja |
| 5 | sankar |
| 6 | office |
| 7 | andrew |
| 8 | sabarish |
| 9 | saravanan |
+----+-----------+
cc_caller_requirement
+----+-------------+--------------+
| id | cc_agent_id | cc_caller_id |
+----+-------------+--------------+
| 1 | 1 | 5 |
| 2 | 1 | 5 |
| 3 | 1 | 2 |
| 4 | 1 | 2 |
| 5 | 1 | 7 |
| 6 | 4 | 2 |
| 14 | 1 | 2 |
| 13 | 5 | 2 |
| 12 | 5 | 2 |
| 15 | 1 | 8 |
| 16 | 1 | 9 |
+----+-------------+--------------+
cc_notifications
+----+-------------+--------------+-------------------+----------------------+
| id | cc_agent_id | cc_caller_id | cc_requirement_id | cc_notification_type |
+----+-------------+--------------+-------------------+----------------------+
| 1 | 1 | 5 | 1 | sms |
| 2 | 1 | 5 | 1 | mail |
| 3 | 1 | 5 | 1 | courier |
| 4 | 1 | 5 | 2 | sms |
| 5 | 1 | 5 | 2 | mail |
| 6 | 1 | 2 | 3 | sms |
| 7 | 1 | 2 | 4 | sms |
| 8 | 1 | 2 | 4 | mail |
| 9 | 1 | 2 | 4 | courier |
| 10 | 1 | 7 | 5 | mail |
| 11 | 1 | 7 | 5 | courier |
| 12 | 4 | 2 | 6 | sms |
| 13 | 4 | 2 | 6 | mail |
| 14 | 4 | 2 | 6 | courier |
| 30 | 5 | 2 | 12 | sms |
| 31 | 5 | 2 | 12 | mail |
| 32 | 5 | 2 | 12 | courier |
| 33 | 5 | 2 | 13 | sms |
| 34 | 5 | 2 | 13 | mail |
| 35 | 5 | 2 | 13 | courier |
| 36 | 1 | 2 | 14 | sms |
| 37 | 1 | 8 | 15 | sms |
| 38 | 1 | 8 | 15 | mail |
| 39 | 1 | 9 | 16 | sms |
| 40 | 1 | 9 | 16 | mail |
+----+-------------+--------------+-------------------+----------------------+
i execute sql query is
SELECT cca.id, cca.username,
(SELECT COUNT(cccr.id)
FROM cc_caller_requirements AS cccr
WHERE cccr.cc_agent_id = cca.id
GROUP BY cccr.cc_caller_id) AS num_of_callers,
(SELECT COUNT(ccns.id)
FROM cc_notifications AS ccns
WHERE ccns.cc_agent_id = cca.id
AND ccns.cc_notification_type_id = 'sms') AS sms,
(SELECT COUNT(ccnm.id)
FROM cc_notifications AS ccnm
WHERE ccnm.cc_agent_id = cca.id
AND ccnm.cc_notification_type_id = 'mail') AS mail,
(SELECT COUNT(ccna.id)
FROM cc_notifications AS ccna
WHERE ccna.cc_agent_id = cca.id
AND ccna.cc_notification_type_id = 'courier') AS courier
FROM cc_agents AS cca
GROUP BY cca.id
I'm looking for output like this:
+------------+---------------+-----------+------------+---------------+
| agent name | no of callers | total sms | total mail | total courier |
+------------+---------------+-----------+------------+---------------+
| sankar | 5 | 7 | 6 | 3 |
| jenifer | 0 | 0 | 0 | 0 |
| andrew | 0 | 0 | 0 | 0 |
| nirmal | 1 | 1 | 1 | 1 |
| raja | 1 | 2 | 2 | 2 |
+------------+---------------+-----------+------------+---------------+
agent name, total sms, total mail and total courier data are working well...
but i get this error " Subquery returns more than 1 row" when i want no of callers
pls help me to solve it

Change your query to:
SELECT cca.id, cca.username,
(SELECT COUNT(DISTINCT cccr.cc_caller_id)
FROM cc_caller_requirements AS cccr
WHERE cccr.cc_agent_id = cca.id
) AS num_of_callers,
(SELECT COUNT(ccns.id)
FROM cc_notifications AS ccns
WHERE ccns.cc_agent_id = cca.id
AND ccns.cc_notification_type_id = 'sms') AS sms,
(SELECT COUNT(ccnm.id)
FROM cc_notifications AS ccnm
WHERE ccnm.cc_agent_id = cca.id
AND ccnm.cc_notification_type_id = 'mail') AS mail,
(SELECT COUNT(ccna.id)
FROM cc_notifications AS ccna
WHERE ccna.cc_agent_id = cca.id
AND ccna.cc_notification_type_id = 'courier') AS courier
FROM cc_agents AS cca
GROUP BY cca.id

Related

MySQL Query idea needed

I have a table, with the students of a class:
+----+-----------+----------+---------+
| id | nume | prenume | absente |
+----+-----------+----------+---------+
| 1 | Radu | Catalina | 0 |
| 2 | Maselusa | Andreea | 0 |
| 3 | Goaga | Ramona | 0 |
| 4 | Stoica | Teodor | 0 |
| 5 | Petrache | Adrian | 0 |
| 6 | Stoica | Dragos | 0 |
| 7 | Florea | Valeriu | 0 |
| 8 | Coleasa | Ionut | 0 |
| 9 | Panait | Andreea | 0 |
| 10 | Vasile | Codrut | 0 |
| 11 | Ungureanu | Costin | 0 |
| 12 | Pantazi | Daniel | 0 |
| 13 | Stroe | Stefan | 0 |
| 14 | Cojocaru | Iulian | 0 |
| 15 | Pirvu | David | 0 |
| 16 | Ion | Raluca | 0 |
| 17 | Olaru | Andreea | 0 |
+----+-----------+----------+---------+
with id, last name, first name and absence.
Then, I have another table:
+----+--------------+---------------+
| id | nume_materie | medie_actuala |
+----+--------------+---------------+
| 1 | Limba romana | 0 |
| 2 | Matematica | 0 |
| 3 | Fizica | 0 |
| 4 | Chimie | 0 |
| 5 | Biologie | 0 |
| 6 | Informatica | 0 |
| 7 | Engleza | 0 |
| 8 | Franceza | 0 |
| 9 | Geografie | 0 |
| 10 | Istorie | 0 |
| 11 | Sport | 0 |
| 12 | Economie | 0 |
| 13 | Psihologie | 0 |
+----+--------------+---------------+
With id, name of the class and actual average grade.
Now, I need to print one of those students with all classes and grades.
Example:
I want to print this in PHP:
Radu Catalina, 0 absences.
Grades:
1. Limba Romana: 8
2. Matematica: 9
3. Fizica: 10 etc. etc. etc.
How can I do this? I have no idea.. I am a beginner. I have some idea about foreign keys and something like that, but I don't know how to use it. Please help.
You can use 'natural join'.
//Example
SELECT table1.*, table2.*
FROM table1,table2
Where table1.nume = 'Radu';
You can insert a foreign key either through create a table or through the alter table.
After creating a table you can use alter table.

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)

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

swapping values in different tables if the data exist then value + 1 if data = 0 then delete

i have this table called bag:
+--------+----------+---------+----------+
| bag_id | chara_id | item_id | item_qty |
+--------+----------+---------+----------+
| 1 | 1 | 2 | 26 |
| 2 | 1 | 1 | 56 |
| 3 | 3 | 1 | 4 |
| 6 | 3 | 4 | 3 |
| 7 | 4 | 4 | 3 |
| 8 | 5 | 4 | 3 |
| 9 | 6 | 4 | 2 |
| 10 | 1 | 5 | 1 |
| 14 | 1 | 8 | 1 |
| 15 | 1 | 6 | 2 |
| 18 | 1 | 4 | 4 |
| 19 | 1 | 3 | 2 |
| 29 | 8 | 1 | 1 |
| 30 | 8 | 7 | 2 |
| 33 | 6 | 2 | 1 |
| 34 | 3 | 5 | 1 |
| 35 | 3 | 8 | 3 |
| 37 | 4 | 3 | 1 |
| 45 | 3 | 3 | 14 |
| 46 | 8 | 2 | 2 |
| 60 | 8 | 5 | 2 |
| 61 | 3 | 2 | 10 |
| 74 | 12 | 2 | 1 |
| 97 | 12 | 5 | 1 |
| 103 | 3 | 6 | 1 |
+--------+----------+---------+----------+
and have this table called equipment:
+----------+----------+-----------+-------------+----------+---------+
| equip_id | chara_id | weapon_id | headgear_id | armor_id | ring_id |
+----------+----------+-----------+-------------+----------+---------+
| 3 | 1 | 4 | 5 | 9 | 8 |
| 5 | 3 | 2 | 5 | 3 | 8 |
| 6 | 4 | 7 | 5 | 3 | 8 |
| 7 | 5 | 4 | 5 | 3 | 8 |
| 8 | 6 | 3 | 5 | 2 | 8 |
| 10 | 8 | 3 | 5 | 2 | 8 |
| 11 | 3 | 2 | 5 | 0 | 8 |
| 12 | 3 | 2 | 5 | 0 | 8 |
| 13 | 12 | 2 | 0 | 0 | 0 |
| 14 | 5 | 4 | 0 | 0 | 0 |
| 15 | 1 | 1 | 0 | 0 | 0 |
| 16 | 1 | 0 | 0 | 6 | 0 |
| 17 | 4 | 4 | 0 | 0 | 0 |
| 18 | 8 | 2 | 0 | 0 | 0 |
| 19 | 3 | 2 | 5 | 0 | 8 |
+----------+----------+-----------+-------------+----------+---------+
scenario:
player equips an item from the bag to equipment:
#unequipping:
1. if equipment id to be unequipped exist in the bag then that bag item = item + 1
else
insert that item to the bag
#equipping:
1. bag item = bag item - 1 where item_id = equipped item_id
else if bag item = 0 then delete it.
basically i want to swap the item's from the equipment to the bag table,
though the twist is the quantity, wherein if that item to be swapped is already existing in the bag table then + 1 to the quantity and if the item from the bag table is = 1 then remove that item from the table and equip that item to the equipment table.
please pm me if you couldn’t understand my situation, its driving me nuts!
this is my current code(if it helps a little):
$fieldnames = array(1=>'weapon', 'armor', 'ring', 'headgear');
if (isset($fieldnames[$equip->item_type])) {
$field = $fieldnames[$equip->item_type].'_id';
$sql_unequip = "INSERT INTO bag(item_id, chara_id, item_qty)VALUES(:item_id, :chara_id, 1) ON DUPLICATE KEY UPDATE item_qty = item_qty + 1";
$sql_equip = "UPDATE equipment SET $field = :item_id WHERE chara_id = :chara_id";
$sql_unequip2 = "DELETE FROM bag WHERE item_id = :item_id AND chara_id = :chara_id AND item_qty = 0";
}

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