Inner join 3 different tables codeigniter - php

I need to join three tables that acquires each other (not centralized to just a table)
1st table: attendance
---------------------------------------------------------------
| id | emp_code | emp_name | date | time |
| 001 | TNY | Tony |01.01.2001| 07.00 |
| 002 | PPR | Pepper |01.01.2001| 07.50 |
---------------------------------------------------------------
2nd table: employee
---------------------------------------------------------
| emp_code | emp_name |division_code| address |
| TNY | Tony | D001 | New york |
| PPR | Pepper | D002 | California|
---------------------------------------------------------
3rd table: division
-----------------------------
|division_code|division_name|
| D001 | Finance |
| D002 | Marketing |
-----------------------------
The result i want to get would be:
-----------------------------------------------------------------------------
| id | emp_code | emp_name |division_name| date | time |
| 001 | TNY | Tony | Finance |01.01.2001| 07.00 |
| 002 | PPR | Pepper | Marketing |01.01.2001| 07.50 |
-----------------------------------------------------------------------------
My code from my model:
function ShowData()
{
$this->db->select('attendance.emp_code, attendance.emp_name,division.division_name,attendance.date,attendance.time');
$this->db->from('attendance');
$this->db->join('employee', 'employee.emp_code = attendance.emp_code');
$this->db->join('division', 'employee.division_code = division.division_code');
$query = $this->db->get();
}
The result of my code is nothing, no data is shown, and i think it is because of my query

Your method isn't returning anything:
$this->db->selct('a.id, a.emp_code, a.emp_name, d.divison_node, a.date, a.time');
$this->db->join('employee AS e', 'e.emp_code = a.emp_code');
$this->db->join('division AS d', 'd.division_code = e.division_code');
return $this->db->get('attendance AS a')->result();

Your code is missing the final data getter:
function ShowData()
{
$this->db->select('attendance.emp_code, attendance.emp_name,division.division_name,attendance.date,attendance.time');
$this->db->from('attendance');
$this->db->join('employee', 'employee.emp_code = attendance.emp_code');
$this->db->join('division', 'employee.division_code = division.division_code');
$query = $this->db->get();
$data = $query->result_array(); // here will be stored the selected data as an array
}
The $this->db->get(); just creates an SQL statement using the CI query builder and executes it, it does not return the SQL output data, you just receive an object of the query itself.
But $query->result_array(); gets the SQL output data and formates the data for you - to an array in this case.
If you want to return the data, just add this line to your function body:
return $data;

Related

Dynamically create MySQL table columns

I have the following MySQL table which is structured like that:
| id | bonus0 |
Now I want to add the following data set:
| id | bonus0 | bonus1 | bonus2 | bonus3 |
| 10 | 4582 | 2552 | 8945 | 7564 |
As you can see the columns bonus1 - bonus3 arenĀ“t created yet.
How would a php script/ query look like which checks if enough columns are already available and if not which will create the missing ones with consecutive numbers at the end of the word "bonus"?
So in the example the columns bonus1 - bonus3 would be created automatically by the script.
In reality (I mean a normalized relational database) you should have 3 tables. Lets call them people, bonuses and bonus_to_person
people looks like:
+-----------------+------------+
| person_id | name |
+_________________+____________+
| 1 | john |
+-----------------+------------+
| 2 | frank |
+-----------------+------------+
bonuses Looks like
+----------------+--------------+
| bonus_id | amount |
+________________+______________+
| 1 | 1000 |
+----------------+--------------+
| 2 | 1150 |
+----------------+--------------+
| 3 | 1200 |
+----------------+--------------+
| 4 | 900 |
+----------------+--------------+
| 5 | 150 |
+----------------+--------------+
| 6 | 200 |
+----------------+--------------+
bonus_to_person Looks like
+----------------+-----------------+
| bonus_id | person_id |
+________________+_________________+
| 1 | 1 |
+----------------+-----------------+
| 2 | 2 |
+----------------+-----------------+
| 3 | 2 |
+----------------+-----------------+
| 4 | 1 |
+----------------+-----------------+
| 5 | 1 |
+----------------+-----------------+
| 6 | 1 |
+----------------+-----------------+
This way, any ONE person can have unlimited bonuses simply by INSERTING into bonuses with the amount, and INSERTING into bonus_to_person with the bonus_id and person_id
The retrieval of this data would look like
SELECT a.name, c.amount from people a
LEFT JOIN bonus_to_people b
ON a.person_id = b.person_id
LEFT JOIN bonuses c
ON c.bonus_id = b.bonus_id
WHERE a.person.id = 1;
Your result from something like this would look like
+------------+----+-------+
| name | amount |
+____________+____________+
| john | 1000 |
+------------+------------+
| john | 900 |
+------------+------------+
| john | 150 |
+------------+------------+
| john | 200 |
+------------+------------+
You should be using this normalized approach for any database that will continue growing -- Growing "deeper" than "wider" is better in your case ..
// Get existing columns of the table
// $queryResult = run SQL query using PDO/mysqli/your favorite thing: SHOW COLUMNS FROM `table`
// Specify wanted columns
$search = ['bonus0', 'bonus1', 'bonus2', 'bonus3'];
// Get just the field names from the resultset
$fields = array_column($queryResult, 'Field');
// Find what's missing
$missing = array_diff($search, $fields);
// Add missing columns to the table
foreach ($missing as $field) {
// Run SQL query: ALTER TABLE `table` ADD COLUMN $field INT
}

Select from table where count from another related table is only one

I've tow tables both are related by id ... I want a single query using eloquent or mysql statements to do below ... :
clients
-----------
| Id | name |
-----------
| 1 | name1|
-----------
| 2 | name2|
-----------
| 3 | name3|
-----------
requests
----------------
| Id | client_id |
----------------
| 1 | 1 |
----------------
| 2 | 1 |
----------------
| 3 | 2 |
----------------
| 4 | 3 |
----------------
| 5 | 3 |
----------------
I just want the result to show just clients that has only one request
result
----------------
| Id | name |
----------------
| 2 | name2 |
----------------
How to make it in mysql or laravel elequent ????
You can try the following
DB::table('requests')->groupBy('client_id')->havingRaw('COUNT(*) = 1')->get();
Assuming you have working eloquent Models and relationships you could do:
Client::has('requests', '=', 1)->get();
The next query should resolve your problem:
SELECT
clients.Id,
clients.name
FROM requests
JOIN clients ON clients.Id = requests.client_id
GROUP BY clients.Id, clients.name
HAVING COUNT(*) = 1
;

Use file_get_contents in PHP Array to Update MySQL

I have a database contains ID and name of my Staff (DATABASE 1):
--------------
| ID | name |
--------------
| 1 | Mr.AA |
| 2 | Mr.AB |
|... | ... |
| 78 | Mr.CZ |
--------------
Then my colleague has the staff absence database per day for 2 years (DATABASE 2):
Tablename: Table_for_Mr.AA
--------------------------
| ID | date | work |
--------------------------
| 1 | 2016-01-01 | Yes |
| 2 | 2016-01-02 | Yes |
| 3 | 2016-01-03 | No |
|... | ... | ... |
|730 | 2017-12-31 | Yes |
--------------------------
Due to our agreement, we hold each database ourselves (2 parties), so each database is stored in different server.
Lately I need to get the data from DATABASE 2 to be shown in my website and I can ask my colleague to make PHP file that return the array for each name (www.colleaguewebsite/staff/absence.php?name=Mr.AA).
I already made the new 'workstat' database (DATABASE 3) in my server with this detail:
---------------------------------
| ID | date | Name | work |
---------------------------------
| 1 | 2016-01-01 |
| 2 | 2016-01-02 |
| 3 | 2016-01-03 |
|... | ... |
---------------------------------
this is the best I can do:
$sourceURL = 'www.colleaguewebsite/staff/absence.php'
$sql1= $conn->query("select * FROM staff ");
while($row_1 = $sql1->fetch_array()){
$name= $row_1 ['name'];
//getting the absence detail from each staff
$json_1 = file_get_contents($sourceURL.'?name='.$name);
$data_1 = json_decode($json_1,true);
foreach($data_1 as $value_1){
$date = $value_1['date'];
$work = $value_1['work'];
//if the correspondence date is exist then update, otherwise add
$sql_2 = $conn->query("select * FROM workstat WHERE date='$date' AND name='$name");
if ($sql_2->num_rows > 0){
$update=$conn->query("UPDATE workstat set name='$name', work='$work' WHERE date='$date' ");
}else{
$addnew=$ob->query("INSERT INTO availability (date, name, work) VALUES ('$date', '$name', '$work'
}
}
}
However, I have some things that bothers:
The required time to execute this script is very long, mostly exceeding the 90 seconds time.
Dirty database. I will have 730 row of data (per day) for each name, so my database 3 will have 730 * 78 person = 56.940 rows with duplicate date (2017-01-01 ... 2017-12-31 for Mr.AA, 2017-01-01 ...2017-12-31 for Mr.AB, etc...).
How can I optimize my code in table design and loading time?
Another method than file_get_contents is okay, I hope it's still PHP.

How to count number of rows with the same column data and display to table?

I have 2 tables, the 'department' and 'document'.
Table department
| doc_id | dept_name |
----------------------------------
| 1 | Information Technology|
| 2 | Software Development |
| 3 | Human Resource |
| 4 | Accounting |
| 5 | Support |
Table document
| doc_id | doc_name | author | description | department |
----------------------------------------------------------------------------
| 1 | Maps | User1 | sample | Information Technology |
| 2 | Audits | User3 | sample | Software Development |
| 3 | Image | User1 | sample | Information Technology |
| 4 | Papers | User4 | sample | Human Resource |
| 5 | Print Screen| User1 | sample | Software Development |
| 6 | Transaction | User3 | sample | Accounting |
| 7 | Graph | User1 | sample | Support |
| 8 | Excel | User1 | sample | Information Technology |
Now, I want to display the table with two columns: department and total_doc.
Output:
| department |total_doc|
-----------------------------------
| Information Technology| 3 |
| Software Development | 2 |
| Human Resource | 1 |
| Accounting | 1 |
| Support | 1 |
I want to display the total document inside the department and arrange them in ascending order.
Here's my query.(not sure)
SELECT department, count(doc_name) as 'total_doc' FROM tbl_document GROUP BY doc_name
I'm using MVC pattern in Codeigniter.
$this->db->select("department, count(doc_name) as 'total_doc'");
$this->db->from('document');
$this->db->group_by('doc_name');
Also, How can I display this in table? like using foreach in html?
You need to do group by with department not with doc_name.
$this->db->select("department, count(doc_name) as 'total_doc'");
$this->db->from('document');
$this->db->group_by('department');
$result = $this->db->get()->result();
Hope This will help you.
foreach ($result as $row)
{
echo $row->department."----".$row->total_doc;
}
here you go
SELECT dept_name,COUNT(td.department) FROM department d
LEFT JOIN tdocument td ON td.`department`=d.`dept_name`
GROUP BY td.`department` ORDER BY COUNT(td.`department`) DESC;
You want one line per department. IN SQL words: You want to group by department.
select department, count(*) as total_doc from document group by department;
(BTW: don't use single quotes for column aliases.)

insert column as header for type

I have a MySql table and I want to list things by type and insert headers. What type of query would I use?
From This:
| Fluffy | Harold | cat | f | 1993-02-04 | NULL |
| Claws | Gwen | cat | m | 1994-03-17 | NULL |
| Buffy | Harold | dog | f | 1989-05-13 | NULL |
| Fang | Benny | dog | m | 1990-08-27 | NULL |
| Bowser | Diane | dog | m | 1979-08-31 | 1995-07-29 |
| Chirpy | Gwen | bird | f | 1998-09-11 | NULL |
| Whistler | Gwen | bird | f | 1997-12-09 | NULL |
| Slim | Benny | snake | m | 1996-04-29 | NULL |
| Dalli | Alli | canine | m | 2001-12-20 | NULL |
| Tara | David | canine | f | 2002-05-17 | NULL |
| Mimi | Alli | guinea pig | m | 2004-05-17 | NULL |
To this:
<h2>Cat</h2>
<ul>
<li>Fluffy</li>
<li>Claws</li>
</ul>
<h2>Dog</h2>
<li>Buffy</li>
<li>Fang</li>
<li>Bowser</li>
</ul>
etc.
Don't try to do all of this with SQL (just do a standard select query), use PHP to group the result, then present it. The best way to do this would be to have an object that will do the grouping for you, as you'll probably need it more than once. For example, your class could look something like this:
<?php
class Arrays
{
public static function group($array,$key)
{
if(NULL == $array)
return NULL;
$grouped = NULL;
foreach($array as $item)
{
$grouped[$item[$key]][] = $item;
}
return $grouped;
}
}
?>
And your use case could be something like:
<?php
$result = ...; // The result of your database query.
$grouped_by_type = Arrays::group($result,"type");
foreach($grouped_by_type as $type => $group)
{
echo "<h2>".ucwords($type)."</h2>";
echo "<ul>";
foreach($group as $animal)
{
echo "<li>".$animal['first_name']."</li>"; // Assumes the query brought back first_name...
}
echo "</ul>";
}
?>
Your first query would be:
SELECT DISTINCT type FROM table ORDER BY type ASC
With your PHP, I am sure you can get a result from this query and loop through it. Next one is to put another query inside the loop that gives you the list of animals that belong to current type:
SELECT name FROM table WHERE type='$type' ORDER BY name ASC
$type is just variable holding current type. I assumed column and table names so please change it to suit your code.

Categories