Codeigniter. How to get sum of database columns - php

I have two tables .
pre_order
receive_pre_order
My Question is how to get all the information from pre_order table and get the SUM of all the quantity received form receive_pre_order table against that pre_order id.
To make it clear suppose we have the following data in recieve_pre_order .
+--------------+------------+-------------------+
| pre_order_id | product_id | quantity_recieved |
+--------------+------------+-------------------+
| 1 | 1 | 10 |
| 1 | 1 | 20 |
| 1 | 1 | 10 |
+--------------+------------+-------------------+
It should return quantity_recieved = 40 against pre_order_id 1 .
Right now I have tried:
$this->db->select_sum('quantity_recieved');
$this->db->from('recieve_pre_order');
return $this->db->get();
It is working but, it is getting data from one table.
But I want to fetch data from both tables.

Join the two tables tables (rpo.pre_order_id = po.id). Group the result for po.id, so all Rows with the same po.id will be grouped into one row. sum(rpo.quantity_recieved) will sum up the quantity for these groups.
select po.id, sum(rpo.quantity_recieved)
from receive_pre_order rpo
join pre_order po on rpo.pre_order_id = po.id
group by po.id;

try this
$this->db->select("sum(recieve_pre_order.quantity_recieved),pre_order.id");
$this->db->from('recieve_pre_order');
$this->db->join("pre_order",'recieve_pre_order.pre_order_id = pre_order.id','left outer');
$this->db->where('recieve_pre_order.pre_order_id',your parameter);

$this->db->select('pre_order.*');
$this->db->select_sum('recieve_pre_order.quantity_recieved');
$this->db->from('pre_order');
$this->db->join("recieve_pre_order",'recieve_pre_order.pre_order_id = pre_order.id','left');

try sub query instead of joining table.
$this->db->select("po.*,SELECT(SUM(quantity_recieved) from receive_pre_order where pre_order_id = po.id) as total_recieved_quantity",FALSE);
$this->db->from('pre_order as po');
return $this->db->get();

Related

SQL need to improve run speed

I am trying to select data from mysql by a date field in the database. (Users can enter start date and end date)
For each selected row between user selected dates, I need to select from the same table to produce a result.
Example:
$query = "SELECT * FROM table WHERE date BETWEEN $begindate AND $enddate"; //Select by date
$result = mysqli_query($dbc,$query);
while($row = mysqli_fetch_array($result)){
vardump($row); //user needs to see all data between date selection
$query = "SELECT * FROM table WHERE field = $row['field']";
// and then do calculations with the data
}
This runs very slowly and I can see why. How can I improve the run speed?
Edit:
The original purpose was to generate a sales report between dates. Now the user wants the report to produce another result. This result could only be produced by searching against the same table, and the rows that I need is not within the date selection.
Edit 2:
I do need to output the entire table between date selection. Each row will need to find ALL other rows where field = field, within or out side of the date selection.
Edit 3: Solved the problem. All the answers are helpful, though I think the chosen answer was most related to my question. However, I believe using join when working with two tables is the right way to go. For my problem, I actually just solved it by duplicating the table and run my search against the duplicated table. The chosen answer did not work for me because the second query selection is not a part of the first query selection. Hope this would help anyone looking at this post. Again, thanks for all the help!
Well, so if you are really looking for such a conditions in same table, I suggest you should use IN selector like following:
$query = "SELECT * FROM table
WHERE field IN
(SELECT DISTINCT field FROM table
WHERE
date BETWEEN $begindate AND $enddate)";
So final code will look some like following:
$query = "SELECT * FROM table
WHERE field IN
(SELECT DISTINCT field FROM table
WHERE
date BETWEEN $begindate AND $enddate)";
$result = mysqli_query($dbc,$query);
while($row = mysqli_fetch_array($result)){
// do calculations with the $row
}
I guess your table names arent TABLE:
just user inner join
$query = "SELECT *
FROM table1
JOIN table2
ON table1.field = table2.field
WHERE date BETWEEN $begindate AND $enddate
ORDER BY table1.field;"
Stop writing pseudo-SQL
SELECT * FROM is technically pseudo-SQL (a sql command which the interpreter has to modify before the command can be executed. It is best to get in a habit of specifying columns in the SELECT statement.
Use SQL joins
Joins are what makes relational databases so useful, and powerful. Learn them. Love them.
Your set of SQL queries, combined into a single query:
SELECT
table1.id as Aid, table1.name as Aname, table1.field as Afield,
table2.id as Bid, table2.name as Bname, table2.field
FROM table table1
LEFT JOIN table table2
ON table1.field = table2.field
WHERE table1.date BETWEEN $begindate AND $enddate
ORDER BY table1.id, table2.id
Your resulting print of the data should result in something which access each set of data akin to:
$previous_table1_id = 0;
while($row = mysqli_fetch_array($result)){
if ($row['Aid'] != $previous_table1_id) {
echo 'Table1: ' . $row['Aid'] . ' - ' . $row['Aname'] . ' - '. $row['Afield'] . "\n";
$previous_table1_id = $row['Aid'];
}
echo 'Table2: ' . $row['Bid'] . ' - ' . $row['Bname'];
}
Dealing with aggregated data
Data-aggregation (multiple matches for table1/table2 on field), is a complex subject, but important to get to know. For now, I'll leave you with this:
What follows is a simplified example of one of what aggregated data is, and one of the myriad approaches to working with it.
Contents of Table
id | name | field
--------------------
1 | foos | whoag
2 | doh | whoag
3 | rah | whoag
4 | fun | wat
5 | ish | wat
Result of query I gave you
Aid | Aname | Afield | Bid | Bname
----------------------------------
1 | foos | whoag | 1 | foos
1 | foos | whoag | 2 | doh
1 | foos | whoag | 3 | rah
2 | doh | whoag | 1 | foos
2 | doh | whoag | 2 | doh
2 | doh | whoag | 3 | rah
3 | rah | whoag | 1 | foos
3 | rah | whoag | 2 | doh
3 | rah | whoag | 3 | rah
4 | fun | wat | 4 | fun
4 | fun | wat | 5 | ish
5 | ish | wat | 4 | fun
5 | ish | wat | 5 | ish
GROUP BY example of shrinking result set
SELECT table1.id as Aid, table1.name as Aname
group_concat(table2.name) as field
FROM table table1
LEFT JOIN table table2
ON table1.field = table2.field
WHERE table1.date BETWEEN $begindate AND $enddate
ORDER BY table1.id, table2.id
GROUP BY Aid
Aid | Aname | field
----------------------------------
1 | foos | foos,doh,rah
2 | doh | foos,doh,rah
3 | rah | foos,doh,rah
4 | fun | fun, ish
5 | ish | fun, ish

need to get result of joining multiple tables as one row

I want to get result of joining multiple tables as one row and fetch multiple cuisine_name from t_cuisine table and get the cuisine_id in t_search.cuisineId column using php (CODEIGNITER) and joins
t_search table to get the cuisineId like this so that I can get the available cuisine names through the cuisineId.
t_search table
searchID|restaurant_name|cuisineId
1 | XYZ | 1,4,5
2 | KIH | 2
3 | GHY | 4,5
4 | UIO | 1,2,3
5 | RTY | 3,5
t_cuisine table
cuisineId|cuisine_name
1 | ABC
2 | CDE
3 | EFG
4 | GHZ
5 | HJL
in my Model i've used
$this->db->select('*');
$this->db->from('t_search');
$this->db->join('t_cuisine','t_cuisine.cuisineId = t_search.cuisineId');
which fetches data only based on single value in cuisineId in t_search.
$this->db->select('*');
$this->db->from('t_search');
$this->db->join('t_cuisine','t_cuisine.cuisineId IN(t_search.cuisineId)');
$this->db->where('t_cuisine.cuisineId', X);
Change X to the ID of the cuisine you are looking for
What you had previously (when your query worked based on a single value in cuisineId) was a one to many relationship. Joining like that worked well because each search had one cuisine.
This is a many to many relationship, and this table structure doesn't support it well. Instead of storing a delimited list in the cuisineId column of your t_search table, you need another table to represent the relationship between search and cuisine, like this:
t_search_cuisine table
searchID|cuisineId
1 | 1
1 | 4
1 | 5
2 | 2
3 | 4
3 | 5
4 | 1
4 | 2
4 | 3
5 | 3
5 | 5
Then you should be able to get all your data with one additional join.
$this->db->select('*');
$this->db->from('t_search');
$this->db->join('t_search_cuisine','t_search.searchID = t_search_cuisine.searchID');
$this->db->join('t_cuisine','t_search_cuisine.cuisineId = t_cuisine.cuisineId');
Based on the structure of your table, joining those table would be not easy. Perhaps you could do with two queries instead.
$this->db->select("cuisineId");
$this->where("searchID", $searchID);
$qry1 = $this->db->get("t_search");
$res1 = $qry1->row_array();
$qry1->free_result();
if ($res1) {
$this->db->select("*");
$this->db->where_in('cuisineId', $res1);
$qry2 = $this->db->get("t_cuisine");
$res2 = $qry2->result();
return ($res2) ? $res2 : false;
}

Converting raw queries into laravel

I have this schema
product_categories
id | product_category
---------------------
1 | ABC
2 | DBC
3 | EBA
store_product_categories
id | category_id | store_id
------------------------
1 | 2 | 11
2 | 1 | 11
3 | 3 | 11
I have created a query in mysql work bench
SELECT pc.* FROM product_categories pc LEFT JOIN store_product_categories spc ON pc.category = pc.id AND spc.store_id = 11 WHERE spc.category IS NULL;
This query actually gets all those categories from product_categories table which are not present in store_product_categories.
Now I am really really confused how to build this is Laravel Eloq..
I did try this.
$exclusive_categories = Product_category::join('store_product_categories','store_product_categories.category_id','=','product_categories.id')
->where('store_product_categories.store_id','=',session('store_id'))
->where('store_product_categories.category_id','=','NULL')->get();
But this doesn't give me result
Since you're joining on two different columns, you need to pass that through a function/closure:
$exclusive_categories = Product_category::leftJoin('store_product_categories', function($join) {
$join->on('store_product_categories.category_id','=','product_categories.id')
->on('store_product_categories.store_id','=',session('store_id'));
})
->where('store_product_categories.store_id','=','NULL')->get();
I'm not sure if this is quite what you want. If you're looking for where store_id is NULL OR store_id = the session id, you can pass that through another closure/function.
$exclusive_categories = Product_category::leftJoin('store_product_categories spc', function ($join) {
$join->on('spc.category_id', '=', 'product_categories.id');
$join->on('spc.store_id', '=', \DB::raw(session('store_id')));
})
->whereNull('spc.category_id')
->get(['product_categories.*']);
$exclusive_categories = Product_category::leftJoin('store_product_categories','store_product_categories.category_id','=','product_categories.id')
->where('store_product_categories.store_id','=',session('store_id'))
->whereNull('store_product_categories.store_id')->get();
https://laravel.com/docs/5.3/queries

PHP + SQL -- Counting clicks in multiple rows

i stuck at the problem that my code wont count total clicks in multiple rows.
This is how the Database looks
id | jb_clicks | created_time
--------------------------------------------------
1 | 14 | 1475420816
2 | 7 | 1475422200
3 | 9 | 1475422217
4 | 3 | 1475422239
I want the result to be 33 (14+7+9+3)
How is this possible?
The current code looks like this:
SELECT COUNT(*) AS jb_clicks FROM jb_urls
my function:
function sumdatabase($select, $statement){
$config = new mysql_config;
$link = mysqli_connect($config::MYSQL_HOST,$config::MYSQL_USER,$config::MYSQL_PASS);
mysqli_select_db($link, $config::MYSQL_DATABASE);
$result = mysqli_query($link,"SELECT SUM(".$config::MYSQL_PREFIX."$select) AS jb_clicks FROM $statement");
$row = mysqli_fetch_assoc($link,$result);
return $row[$config::MYSQL_PREFIX.$select];
}
Use the following:
SELECT SUM(jb_clicks) AS jb_clicks FROM jb_urls
COUNT() is used to count the row numbers and SUM() is to calculate the total sum of a column in a table. In your case, it would be SUM(jb_clicks).

Sum with WHERE and GROUP BY CLAUSE

Good day. I am really in big trouble as I can't figure what is wrong with my statement. It is as follows:
$sumitem = mysqli_query($conn,"SELECT SUM(AMOUNT) AS TOTAL FROM sum_query WHERE MAIN_ID = 1 GROUP BY ITEM_ID");
$sum = mysqli_fetch_assoc($sumitem);
I am trying to print $sum['TOTAL'] but what it shows the first column only. Below is my sample table:
MAIN_ID | ITEM_ID | AMOUNT | DESC | OTHER_DETAILS
1 | 1 | 500 | Item 1 | a
1 | 2 | 5000 | Item 2 | a
1 | 2 | 5000 | Item 2 | b
My desired result should be 5500 but it only returns 500.
Thank you very much.
If you want ans as 6500 then remove group by clause
SELECT SUM(AMOUNT) AS TOTAL FROM sum_query WHERE MAIN_ID = 1
SELECT SUM(g.AMOUNT) AS TOTAL
FROM sum_query g
WHERE g.MAIN_ID = 1
GROUP BY g.ITEM_ID
This query is working plase try out this
You are having 2 records for Item 2. and i don't know why you are keeping 'a and b' in OTHER_DETAILS.
Your requirement is not clear
If you want to take only the records matching with OTHER_DETAILS 'a',then use the following query
SELECT SUM(AMOUNT) AS TOTAL FROM sum_query WHERE MAIN_ID = 1 and OTHER_DETAILS = 'a'

Categories