I am having a problem producing a result with my query. I wanted to produce SUM of the result of rows from another table which is related to the primary table.
What I failed to output is the sum of payments, and the sum of payables.
PROBLEM #1 - I cannot produce a correct output of the Payments. The
query seemed to produce an formula of numrows * sum_of_payments
PROBLEM #2 - I cannot produce an output of the total payables.
I am using Codeigniter 3 and this is my model.
function fetch_billing_records($case_id, $patient_id, $status) {
$this->db->join('cases', 'cases.id = billing.case_id', 'left');
$this->db->join('patients', 'patients.id = cases.patient_id', 'left');
$this->db->join('users', 'users.username = billing.user', 'left');
$this->db->join('billing_payments', 'billing_payments.billing_id = billing.id', 'left');
$this->db->join('billing_items', 'billing_items.billing_id = billing.id', 'left');
$this->db->join('services', 'services.title = billing_items.service', 'left');
$this->db->select('
billing.id,
billing.remarks,
billing.status,
billing.created_at,
billing.updated_at,
users.name as user,
users.username,
cases.id as case_id,
cases.title as case_title,
patients.id as patient_id,
CONCAT(patients.lastname, ", ", patients.fullname) as patient_name,
SUM(billing_payments.amount) as payments,
SUM((services.amount - billing_items.discount)*billing_items.qty) as payables
');
if(is_int($case_id)) {
$this->db->where('billing.case_id', $case_id);
}
if(is_int($patient_id)) {
$this->db->where('patients.id', $patient_id);
}
if(is_int($status)) {
$this->db->where('billing.status', $status);
}
$this->db->group_by('billing.id');
$this->db->where('billing.is_deleted', 0);
$query = $this->db->get("billing");
log_message('error', $this->db->last_query());
if ($query->num_rows() > 0) {
return $query->result_array();
}
return false;
}
I saved the Last Query with the Last Query and Log Helpers, and it seemed that the query for my instance is
SELECT `billing`.`id`, `billing`.`remarks`, `billing`.`status`, `billing`.`created_at`, `billing`.`updated_at`, `users`.`name` as `user`, `users`.`username`, `cases`.`id` as `case_id`, `cases`.`title` as `case_title`, `patients`.`id` as `patient_id`, CONCAT(patients.lastname, ", ", patients.fullname) as patient_name, SUM(billing_payments.amount) as payments, SUM((services.amount - billing_items.discount)*billing_items.qty) as payables
FROM `billing`
LEFT JOIN `cases` ON `cases`.`id` = `billing`.`case_id`
LEFT JOIN `patients` ON `patients`.`id` = `cases`.`patient_id`
LEFT JOIN `users` ON `users`.`username` = `billing`.`user`
LEFT JOIN `billing_payments` ON `billing_payments`.`billing_id` = `billing`.`id`
LEFT JOIN `billing_items` ON `billing_items`.`billing_id` = `billing`.`id`
LEFT JOIN `services` ON `services`.`title` = `billing_items`.`service`
WHERE `billing`.`is_deleted` =0
To guide you more with my present problem, this is the schema of the related tables:
and this is the schema of the entire database.
Use group by statement. because mysql aggregate functions work well with group by. if you want billing sum against patient then use following query
SELECT
`billing`.`id`,
`billing`.`remarks`,
`billing`.`status`,
`billing`.`created_at`,
`billing`.`updated_at`, `
users`.`name` as `user`,
`users`.`username`,
`cases`.`id` as `case_id`,
`cases`.`title` as `case_title`,
`patients`.`id` as `patient_id`,
CONCAT(patients.lastname, ", ", patients.fullname) as patient_name,
SUM(billing_payments.amount) as payments,
SUM((services.amount - billing_items.discount)*billing_items.qty) as payables
FROM `billing`
LEFT JOIN `cases` ON `cases`.`id` = `billing`.`case_id`
LEFT JOIN `patients` ON `patients`.`id` = `cases`.`patient_id`
LEFT JOIN `users` ON `users`.`username` = `billing`.`user`
LEFT JOIN `billing_payments` ON `billing_payments`.`billing_id` = `billing`.`id`
LEFT JOIN `billing_items` ON `billing_items`.`billing_id` = `billing`.`id`
LEFT JOIN `services` ON `services`.`title` = `billing_items`.`service`
WHERE `billing`.`is_deleted` =0
GROUP BY patients.id
Related
Problem desc.
I have databese called demo. In this databse i have columns. Two of them are otk and zamestnanci.
/*zamestnanci = employees*/
So i have some data in otk table:
/*otk columns: id_otk|ciarovy_kod|cislo_zakazky|zamestnanci|*/
/*id_otk = autoincrement*/
/*zamestnanci can be only number*/
INSERT INTO otk (ciarovy_kod, cislo_zakazky, zamestnanci) VALUES ('65464', '564', '1');
And now i have some data in zamestnanci:
/*zamestnanci columns: id_zamestnanci|titul|meno|titulz|*/
/*id_zamestnanci = autoincrement*/
INSERT INTO zamestnanci (titul, meno, titulz) VALUES ('ads', 'John', 'das');
And now here is my code for displaing and searching data from otk:
if(isset($_GET['hladat']))
{
$hladatHodnotu = $_GET['hladatHodnotu'];
// hladat v setkych stlpcoch
// pouzitie concat funkcie pre vyhladanie iba urciteho stlpca
$sql = "SELECT * FROM otk JOIN zamestnanci ON zamestnanci.id_zamestnanci=otk.zamestnanci
JOIN zariadenia ON zariadenia.id=otk.zariadenie
JOIN stav ON stav.id=otk.stav
JOIN technologie ON technologie.id=otk.technologie
JOIN obrazky ON obrazky.id_obrazky=otk.obrazok
WHERE CONCAT(`ciarovy_kod`) LIKE '%".$hladatHodnotu."%'";
$vysledokHladania = filtrovatTabulku($sql);
}
//Zobrazovanie dat z viacerych tabuliek do jednej
/* JOIN zamestnanci ON zamestnanci.id_zamestnanci=otk.zamestnanci
JOIN zariadenia ON zariadenia.id=otk.zariadenie
JOIN stav ON stav.id=otk.stav
JOIN technologie ON technologie.id=otk.technologie
JOIN obrazky ON obrazky.id_obrazky=otk.obrazok*/
else {
$sql = "SELECT * FROM otk JOIN zamestnanci ON zamestnanci.id_zamestnanci=otk.zamestnanci
JOIN zariadenia ON zariadenia.id=otk.zariadenie
JOIN stav ON stav.id=otk.stav
JOIN technologie ON technologie.id=otk.technologie
JOIN obrazky ON obrazky.id_obrazky=otk.obrazok";
//$sql = "SELECT * FROM zariadenia, otk WHERE zariadenia.id=otk.zariadenie";
$vysledokHladania = filtrovatTabulku($sql);
}
// funkcia na pripojenie a spustenie $sql
function filtrovatTabulku($sql)
{
//Zahrnut pripojenie k db
include'../db/dbinfo.php';
$vysledokHladania = mysqli_query($con, $sql);
return $vysledokHladania;
}
And now when i empty table "zamestnanci" it will not display data from "otk" with id of that "zamestnanci" because he do not exist. So i want to ask you if there is way how to display if "zamestnanci" is not exist.
You're using the wrong JOIN.
You should learn how each join works before using them, read more about them here http://www.sql-join.com/sql-join-types/
Please help me to check my query. I have search a lot and I have'nt try to select 3 tables before.
I think I got it right but I dont know why there's nothing happen.
public function delSection($delete_id)
{
$stmt = $this->conn->prepare("SELECT * FROM tbl_section
JOIN tbl_login ON (tbl_login.sec_id = tbl_section.sec_id)
JOIN tbl_content ON (tbl_content.sec_id = tbl_section.sec_id)
WHERE tbl_section.sec_id=:del_id");
$stmt->execute(array(":del_id"=>$delete_id));
while($linkRow=$stmt->fetch(PDO::FETCH_ASSOC))
{
unlink(__DIR__."/Admin/cover_images/".$linkRow['sec_cover']);
unlink(__DIR__."/Admin/Files/".$linkRow['sec_id']."/".$linkRow['file_name']);
rmdir(__DIR__."/Admin/Files/".$linkRow['sec_id']);
}
$stmt2 = $this->conn->prepare("DELETE tbl_section, tbl_login, tbl_content FROM tbl_section
JOIN tbl_login ON (tbl_login.sec_id = tbl_section.sec_id)
JOIN tbl_content ON (tbl_content.sec_id = tbl_section.sec_id)
WHERE tbl_section.sec_id=:del_id");
$stmt2->bindparam(":del_id",$delete_id);
$stmt2->execute();
return true;
}
What I am trying to do is to select * from 3 tables and fetch their data with fk sec_id
here's the manual running of query
link:
Code:
Done With LEFT OUTER JOIN QUERY
$stmt = $this->conn->prepare("SELECT * FROM tbl_section
LEFT OUTER JOIN tbl_login ON (tbl_login.sec_id = tbl_section.sec_id)
LEFT OUTER JOIN tbl_content ON (tbl_content.sec_id = tbl_section.sec_id)
WHERE tbl_section.sec_id=:unlink_id");
I'm getting started with JOIN and I'm trying to fetch all rows from clasificados and the abrev and nombre column from five of the "JOINED" tables, may be this is not possible but I've being reading about and I thought that it was.
I'm using LIMIT
I'm getting 0 as rowCount. Anyone could guide me please?
$sql2 = "SELECT cl.id AS clasid,
cl.email AS email,
cl.tipo_anuncio AS tipo_anuncio,
cl.reid AS reid,
cl.rcid AS rcid,
cl.img_1 AS img_1,
cl.titulo AS titulo,
cl.precio AS precio,
cl.negociable AS negociable,
cl.estado_art AS estado,
cl.intercambio AS intercambio,
cl.retro AS retro,
cl.id_cat_1 AS id_cat_1,
cl.id_subcat_1 AS id_subcat_1,
cl.id_subcat_2 AS id_subcat_2,
cl.clas_pass AS clasified_key,
cl.user_activo AS user_activo,
cl.approved_pay AS approved,
cl.expiracion AS expiracion,
cl.rep_email_enviado AS rep_email_sent,
eid.abrev AS edm_abrev,
cid.nombre AS cdm_nombre,
negoc.nombre AS neg,
exch.nombre AS exchangable,
estadoTB.nombre AS estado_articulo
FROM clasificados AS cl
JOIN 1_ AS cat_one
ON cat_one.id = cl.id_cat_1
JOIN estados AS eid
ON eid.id = cl.reid
JOIN municipios AS cid
ON cid.id = cl.rcid
JOIN negociable_tb AS negoc
ON negoc.id = cl.negociable
JOIN intercambio_tb AS exch
ON exch.id = cl.intercambio
JOIN estado_articulo_tb AS estadoTB
ON estadoTB.id = cl.estado_art
WHERE cl.user_activo = 1 AND cl.approved_pay = 1 ORDER BY cl.id DESC LIMIT $position, $items_per_group";
Okay, I've been tasked with rewriting a small, old PHP app in Codeigniter, and I ran into a bit a road bump. I'm not sure how to go about handling the joins in the query.
FROM(
(
(
(
(mobiledoc.labdata labdata JOIN mobiledoc.items items
ON (labdata.ItemId = items.itemID)
) JOIN mobiledoc.enc enc
ON (labdata.EncounterId = enc.encounterID)
) JOIN mobiledoc.users users_patient
ON (users_patient.uid = enc.patientID)
) JOIN mobiledoc.users users_Provider
ON (users_Provider.uid = enc.doctorID)
) JOIN mobiledoc.facilitygroupmembers facilitygroupmembers
ON (enc.facilityId = facilitygroupmembers.FacilityId)
)
And then after that FROM there are a few more joins, which I think would be fairly easy.
JOIN mobiledoc.facilitygroups facilitygroups ON (facilitygroups.Id = acilitygroupmembers.GroupId)
JOIN mobiledoc.patients patients ON (enc.patientID = patients.pid)
Any help would be greatly appreciated.
UPDATE:
I decided to just put the nested joins inside the for statement, and move on. Here's the original query.
$result = mysql_query("SELECT patients.ControlNO AS PatientID, users_patient.ulname AS patulname,
users_patient.ufname AS patufname, users_patient.uminitial AS patuminitial, users_patient.dob AS
patdob, users_Provider.ulname AS ULname, users_Provider.ufname AS UFname, items.itemName,
labdata.Notes,enc.date, enc.startTime FROM(((((mobiledoc.labdata labdata JOIN mobiledoc.items
items ON (labdata.ItemId = items.itemID)) JOIN mobiledoc.enc enc ON (labdata.EncounterId =
enc.encounterID)) JOIN mobiledoc.users users_patient ON (users_patient.uid = enc.patientID)) JOIN
mobiledoc.users users_Provider ON (users_Provider.uid = enc.doctorID)) JOIN
mobiledoc.facilitygroupmembers facilitygroupmembers ON (enc.facilityId =
facilitygroupmembers.FacilityId)) JOIN mobiledoc.facilitygroups facilitygroups ON
(facilitygroups.Id = facilitygroupmembers.GroupId) JOIN mobiledoc.patients patients ON
(enc.patientID = patients.pid) WHERE (facilitygroups.Name = '". $_POST['facility_id'] . "') AND
(items.itemName LIKE '%X RAY%' OR items.itemName LIKE '%Cast%' OR items.itemName LIKE '%Splint%'
OR items.itemName LIKE '%DEXA%') AND (enc.VisitType NOT IN ('', 'MT', 'TEL')) AND (enc.`date` =
'" . $_POST['txtYear'] . "-" . $_POST['txtMonth'] . "-" . $_POST['txtDay'] ."') ORDER BY
enc.startTime ASC") or die ("could not execute query!");
Here's the new query:
$this->db->select('patients.ControlNO as id');
$this->db->select('users_patient.ulname as lastName');
$this->db->select('users_patient.ufname as firstName');
$this->db->select('users_patient.uminitial as mInitial');
$this->db->select('users_patient.dob as dob');
$this->db->select('users_Provider.ulname as phys_lastName');
$this->db->select('items.itemName');
$this->db->select('labdata.notes');
$this->db->select('enc.date');
$this->db->select('enc.startTime');
$this->db->from('((((mobiledoc.labdata labdata JOIN mobiledoc.items items ON (labdata.ItemId
= items.itemID)) JOIN mobiledoc.enc enc ON (labdata.EncounterId = enc.encounterID)) JOIN
mobiledoc.users users_patient ON (users_patient.uid = enc.patientID)) JOIN mobiledoc.users
users_Provider ON (users_Provider.uid = enc.doctorID)) JOIN mobiledoc.facilitygroupmembers
facilitygroupmembers ON (enc.facilityId = facilitygroupmembers.FacilityId)) JOIN
mobiledoc.facilitygroups facilitygroups ON (facilitygroups.Id = facilitygroupmembers.GroupId)
JOIN mobiledoc.patients patients ON (enc.patientID = patients.pid)');
$this->db->where($where_array);
$this->db->like($like_array);
$this->db->or_like($or_like_array);
$this->db->where_not_in('enc.VisitType', $not_in);
$this->db->order_by('enc.startTime', 'asc');
$this->db->get();
And the output from that query:
SELECT `patients`.`ControlNO` as id, `users_patient`.`ulname` as lastName,
`users_patient`.`ufname` as firstName, `users_patient`.`uminitial` as mInitial,
`users_patient`.`dob` as dob, `users_Provider`.`ulname` as phys_lastName, `items`.`itemName`,
`labdata`.`notes`, `enc`.`date`, `enc`.`startTime` FROM ((((((mobiledoc.labdata labdata JOIN
mobiledoc.items items ON (labdata.ItemId = items.itemID)) JOIN mobiledoc.enc enc ON
(labdata.EncounterId = enc.encounterID)) JOIN mobiledoc.users users_patient ON (users_patient.uid
= enc.patientID)) JOIN mobiledoc.users users_Provider ON (users_Provider.uid = enc.doctorID))
JOIN mobiledoc.facilitygroupmembers facilitygroupmembers ON (enc.facilityId =
facilitygroupmembers.FacilityId)) JOIN mobiledoc.facilitygroups facilitygroups ON
(facilitygroups.Id = facilitygroupmembers.GroupId) JOIN mobiledoc.patients patients ON
(enc.patientID = patients.pid)) WHERE `facilitygroups`.`Name` = 0 AND `enc`.`date` = '12/05/2014'
AND `enc`.`VisitType` NOT IN ('', 'MT', 'TEL') AND `items`.`itemName` LIKE '%X RAY%' OR
`items`.`itemName` LIKE '%DEXA%' OR `0` LIKE '%items.itemName%' ORDER BY `enc`.`startTime` asc
With CI's active record you can easily join tables by using the following format
$qry = $this->db->select('*')
->from('table1')
->where('table1.id', 1)
->join('table2','table2.t_id = table1.id')
->get();
For more information take a look at CI's active record documentation
Also you can specify the join type by adding a third parameter to the join() function
$this->db->join('table3', 'table3.id = table2.t_id', 'left');
I have php/mysql script running which is like this:
$sql = "select a.column1 from table1 a";
$query = mysql_query($sql);
while ($fec = mysql_fetch_assoc($query)) {
$sub1 = "select column1,column2 from subtable1 where id=" . $fec['a.column1'];
$subquery1 = mysql_query($sub1);
while ($subfec1 = mysql_fetch_assoc($subquery1)) {
//all data .....
}
$sub1 = "select column1,column2 from subtable2 where id=" . $fec['a.column1'];
$subquery2 = mysql_query($sub2);
while ($subfec2 = mysql_fetch_assoc($subquery2)) {
//all data .....
}
$sub2 = "select column1,column2 from subtable3 where id=" . $fec['a.column1'];
$subquery3 = mysql_query($sub3);
while ($subfec3 = mysql_fetch_assoc($subquery3)) {
//all data .....
}
}
Now I've many many many records in table1, subtable1, subtable2 and subtable3. And problem is that it takes around 7 hours to display the results. Moreover the CPU Usage is 100%
Please suggest the optimization tips to overcome this issue.
Use a single query to get all records
SELECT
a.column1,
s.column1,
s.column2,
s2.column1,
s2.column2,
s3.column1,
s3.column2
FROM table1 a
LEFT JOIN subtable1 s ON s.id = a.column1
LEFT JOIN subtable2 s2 ON s.id = a.column1
LEFT JOIN subtable3 s3 ON s.id = a.column1
Here
$sql="
SELECT
a.column1 acolumn1,
s.column1 scolumn1,
s.column2 scolumn2,
s2.column1 s2column1,
s2.column2 s2column2,
s3.column1 s3column1,
s3.column2 s3column2
FROM table1 a
LEFT JOIN subtable1 s ON s.id = a.column1
LEFT JOIN subtable2 s2 ON s.id = a.column1
LEFT JOIN subtable3 s3 ON s.id = a.column1";
$query=mysql_query($sql);
while ($fec=mysql_fetch_assoc($query)) {
// display any info here
}
Use aliases for accessing different table columns