MySQL Query to Select dependent rows from Joined tables - php

I'm working on a codeigniter project.
Here are my tables
category
cid cname
5 general
6 science
7 math
books
bid bname
12 first
13 second
14 third
15 fourth
16 fifth
17 sixth
dir
id bid cid
1 12 5
2 13 6
3 14 7
4 15 6
5 16 5
6 17 5
As you can see joining the tables is easy but here is what I need to do.
Create a function that will give me category name(cname) and the number of books in that category. For example the outcome should be like
general 3
science 2
math 1
here is my WIP model
function category_details(){
$this->db->order_by('cname','asc');
$query=$this->db->query('Select * from dir join category on category.cid=dir.cid join books on dir.bid=books.bid');
return $query->result_array();
}
Any help would be much appreciated.

The query should be like this to get expected result
Select category.cname,count(dir.cid) from dir join category on category.cid=dir.cid join books on dir.bid=books.bid group by category.cname
And your function should be like this
function category_details(){
$this->db->order_by('cname','asc');
$query=$this->db->query('Select category.cname,count(dir.cid) from dir join category on category.cid=dir.cid join books on dir.bid=books.bid group by category.cname');
return $query->result_array();
}
you can refer this code COUNT / GROUP BY with active record? for proper CI query.

Related

How to get data from different tables in MySQL database and display in a table with php

I have read many topics but none have given me exactly what i need
I have 3 tables
products
id
product_name
1
Heineken
2
Budweiser
transaction
id
user_id
date
amount
32
4
01/23/2023
10000
45
2
01/23/2023
20000
57
4
01/23/2023
5000
transaction_details
id
transaction_id
product_id
1
32
1
2
32
2
3
45
2
4
45
1
5
57
1
Now how can i achieve this
SELECT FROM transaction WHERE user_id = 4 then use the results to SELECT FROM transaction_details and display it in a table using a single sql query
And when displaying the results from transaction_details i want to use product_name
This is the result i want
transaction_id
products_id and name
32
1. Heineken
32
2. Budweiser
57
1. Heineken
I have tried to select from transaction table where id is equal to 4 and i got two results, i don't know what to do next
Using Mysqli Join Query with select concat option in in your select query
Please Using This Way
select tran.id,CONCAT(pro.id,'.',pro.product_name) as products_id_and_name from transaction as tran join transaction_details as trand on tran.id = trand.transaction_id JOIN products as pro on pro.id = trand.product_id WHERE tran.user_id = 4;

eloquent query for getting difference of two columns from different table

I've to show the remaining quantity of books using eloquent query.
I can get total number of purchased books from this table
ordered_books
BOOKCODE[varchar(10)] QUNATITY[varchar(6)]
111 25
423 15
201 10
111 10
423 10
201 5
158 12
At first I've to sum the total books for each of the book code. Then from the another table I've to calculate the difference.
books_out
DISTRIBUTOR[varchar(50)] BOOKCODE[varchar(10)] QUNATITY[varchar(6)]
25 158 2
35 201 5
45 158 5
55 111 10
35 111 5
15 423 1
25 423 10
Again, from this table I've to calculate the total number of books taken by distributors then I can get the actual number of books present. How shall I write eloquent query for this scenario?
Try to use Raw query like this
==================================
$data=DB::select(DB::Raw("select t1.BOOKCODE,(total-selled) as available from (select BOOKCODE, SUM(QUNATITY) as total FROM `ordered_books` group by `BOOKCODE`) as t1,(SELECT BOOKCODE,SUM(QUNATITY) as selled FROM `books_out` group by `BOOKCODE`) as t2 where t1.BOOKCODE=t2.`BOOKCODE`"));
print_r($data);
//To get total books for each of the book code
SELECT BOOKCODE,SUM(QUNATITY) FROM `ordered_books` group by `BOOKCODE`
//To get total books_out for each of the book code
SELECT BOOKCODE,SUM(QUNATITY) FROM `books_out` group by `BOOKCODE`
Regarding your scenario, I think you require this query, please try it and comment whether it was helpful or not.
$countBooks = DB::select(DB::Raw(" SELECT A.TOTAL, IFNULL(B.SOLD,0) AS SOLD, (A.TOTAL - IFNULL(B.SOLD,0)) AS REMAINING FROM
(
select t1.BookID, SUM(t1.QUNATITY) AS TOTAL from ordered_books t1
GROUP BY t1.BookID) A
LEFT JOIN
(
SELECT BookCode, IFNULL(SUM(Quantity),0) AS SOLD FROM books_outs GROUP BY BookCode) B
ON A.BookID = B.BookCode
"));
dump($countBooks);
Also, better to display the name of books rather than code. It will be more user friendly. Thank You!!!

mysql 2 tables updation/deletion based on condition

Hello friends I have 2 Mysql tables with 1:N relationship between category and category_Dates
Category:
ID Category Frequency
1 Cat A Half-yearly
2 Cat B Quarterly
category_Dates:
ID CatID Date
1 1 01-Jan-15
2 1 01-Jul-15
3 2 01-Jan-15
4 2 01-Apr-15
5 2 01-Jul-15
6 2 01-Oct-15
based on the category frequency I am entering number of records automatically in category_date. Eg
When category frequency = quarterly, I am entering 4 records in category_date with ID of that category. And dates will be entered later.
I am little confused if in case on wants to edit the frequency from halfyearly to yearly. How to change number of records. Please help with your valuable suggestions. I am using laravel 4 framework with mysql
best way would be with 3rd table joining Dates and Categories. See little carefully ,you can see its actually Many to Many relationship (N to N) as 1 category can have multiple dates. and one date may be part of multiple categories, like say 01-Jan-15 is part of Category 1 and 2 as well.
So use
category table
id Category Frequency
1 Cat A Half-yearly
2 Cat B Quarterly
date table
id Date
1 01-Jan-15
2 01-Apr-15
3 01-Jul-15
4 01-Oct-15
categories_dates table
ID CatID Date_id
1 1 1
2 1 3
3 2 1
4 2 2
5 2 3
6 2 4
If you change the frequency in Category table, retrieve the update category_id,
delete all from category_dates where CatId=category_id then insert the new entries in category_Dates.
Hope this help.
I assume your models are Category and CategoryDates.
let's update category id 1 from Half-yearlyto to Quarterly
$query = Category::find(1);
$query -> Frequency = 'Quarterly';
$query -> save();
return $query -> id;
in the CategoryDates model you would delete the catID = 1 and insert new data
$catID = 1;
$query = CategoryModel::where('CatId',$catId) -> delete();
$data = ['CatId' => $catID,'date' => 01-Jan-15, ....];
CategoryModel::create($data);
of course assuming that you would return the newly updated category id to your controller and call a funtionn to do the update in your CategoryModel.
Hope this help.

Exclude result from MySQL query in JOIN

I have multiple tables with orders and deliveries and I want to get only open orders (only those orders that do not have records in delivery table).
So, my tables look like:
Orders table (sh_comenzi):
id partner
1 Partner X
2 Partner Y
3 Partner Z
4 Partner Q
Order lines table (sh_comenzi_pos) where idc is the id of sh_comenzi table
id idc cPos quantity
1 1 1 5
2 1 2 10
3 1 3 20
4 2 1 10
5 2 2 15
6 3 1 10
7 3 2 5
8 3 3 8
9 4 1 15
The deliveries items table is (sh_delivery_items)
id idc cPos
1 1 1
2 1 3
3 2 2
4 3 1
5 3 2
6 3 3
The desired result should give me an output of open orders just like this:
id partner
1 Partner X
2 Partner Y
4 Partner Q
The result doesn't have to keep track o quantities, just on lines level. If one line from orders exists in sh_delivery_items then that line is closed.
I tried something like this:
SELECT DISTINCT sh_comenzi.id, partner FROM sh_comenzi
LEFT JOIN sh_comenzi_pos ON sh_comenzi.id = sh_comenzi_pos.idc
LEFT JOIN sh_delivery_items ON (sh_comenzi_pos.idc = sh_delivery_items.idc AND sh_comenzi_pos.cPos = sh_delivery_items.cPos)
WHERE sh_comenzi.id IS NOT NULL
ORDER BY sh_comenzi.id DESC
Could someone help me?
This is the query you need:
SELECT DISTINCT c.*
FROM sh_comenzi c
INNER JOIN sh_comenzi_pos p
ON c.id = p.idc
LEFT JOIN sh_delivery_items di # 'di' from 'delivery items'
ON p.idc = di.idc AND p.cPos = di.cPos
WHERE di.id IS NULL # keep only not-delivered items
How it works
It combines all the orders (table sh_comenzi) with their line items (table sh_comenzi_pos). The INNER JOIN will leave out the empty orders (if any); if you need them then use LEFT JOIN instead.
Next, each row (order, line item) is combined with the delivery information (table sh_delivery_items) using the pair of columns (idc, cPos). The LEFT JOIN ensures all the rows from the left side table (or result set) appear in the final result set; if a row from the right side table cannot be found to match the row from the left, a row full of NULLs is used instead. This happens for the line items that were not delivered yet (there is no record for them in sh_delivery_items).
Then, the WHERE clause keeps only the rows having NULLs in the di table (sh_delivery_items), i.e. the line items that were not delivered, together with the orders that own them.
Finally, SELECT DISTINCT c.* selects only the columns from the orders table (sh_comenzi) and DISTINCT ensures each order appear only once. Otherwise, each order appears once for each of its line items that was not delivered.
Complete the query yourself with the desired ORDER BY clause.

Query and table - MAX and Join

Still very new to all of this so bear with me.
Have 3 tables
table 1: member
Mem_index, Mem_name
1 joe
2 Mark
Table 2: Course
Course_index, Course_Name
1 Math
2 Reading
Table 3 : data
Data index,Member,Course,Score
1 1 1 85
2 1 2 75
3 2 1 95
4 1 2 65
SO what I would like to do is create a table:
Do a query and gather all of the courses, find the max score for each course and attribute the member name to it.
Table result should look like:
Course, Max score,name
Math 95 Mark
Reading 75 Mark
I can do the query individually but unsure of how to loop it and then propogate the data into the table.
How about this query for SQL?
SELECT c.course_name, MAX( d.score ), m.mem_name
FROM members m
JOIN data d on m.mem_id = d.member
JOIN course c on c.course_id = d.course
GROUP BY d.course
ORDER BY d.score, m.mem_name, c.course_name
Not sure if the field names match up but you get the idea - tested this in sql with some dummy data.
Data
Index Member Course Score
1 1 1 60
1 1 1 85
Course
course_id course_name
1 Math
2 English
3 Science
Members
mem_id mem_name
1 Mark
2 James
You will get the following
Course Name Score Member
Math 85 Mark
Try this query :
SELECT c.course_Name , MAX(d.score),m.mem_name
FROM data d
JOIN course c ON d.course=c.course_index
JOIN members m ON m.mem_index = d.member
GROUP BY d.course
ORDER by MAX(d.score) DESC

Categories