I have 3 tables 'Company', 'Company_Officer', 'Officer'. Companies are unique and Officers are unique but officer could work for multiple companies with different roles therefore Company (1) - (many) Company_Officer (many) - (1) Officer.
Company:
Company_ID
Company_Name
Company_Officer:
Company_Officer_ID
Company_ID
Officer_ID
Officer_Role
Officer:
Officer_ID
Officer_Name
Here is how I fill out Company & Officer tables
foreach($YQL->getConstituents() as $key=>$companyName){
$company[$key] = new Company($companyName);
if($company[$key]->getCompanyFound()==true){
array_push($Company_Details,array($company[$key]->getCompanyName(),$company[$key]->getCompanyNumber(),"FTSE 100"));
foreach ($company[$key]->getCompanyOfficers() as $officer){
array_push($Officer_Details,array($officer[0],$officer[2]));
}
}
}
$Company_Details = array_unique($Company_Details, SORT_REGULAR);
$Officer_Details = array_unique($Officer_Details, SORT_REGULAR);
$DAO->insertMultiOnDuplicateData("Company_Details", array("Company_Name","Company_Number", "Company_Index"), $Company_Details, array("Company_Index"));
$DAO->insertMultiData("Officer_Details", array("Officer_Name","Officer_Resigned"), $Officer_Details);
If a record of Officer/Company already exists only additional fields would be updated the whole row will not be inserted again since Officers/Companies are unique.
But I have no idea how to fill out Company_Officer since it requires Company_ID & Officer_ID which I don't have while executing this code is there a simple solution to this problem? Should I just insert Officers/Companies then get them all back from database to receive IDs of companies and officers and compare to arrays that I have used to update the database?
Related
this is my first question. Apologies if I don't conform with the required rules. I have tried my best and
Problem--
I have a problem with a project am working on. It is medical based. I have these three tables that I need to get reports from
DB structure--
diseaseTable which has columns
diseaseID | diseaseName
diseaseID stores an integer i.e 1, 3, 4,..
dieseaseName stores name of disease e.g Hypertension, Malaria, ..e.tc
I also have patientsTable which has these key columns
patientID - which is an autoincrement int
patientName - name of patient
created_at - date and time of registration of the patient
Lastly there is treatment table which contains
treatmentID -autoincrement int
patient - contains the id of the patient which is a foreing key of patientsTable
created_at and updated_at for timestamps
diseaseTreated (which is my column of interest) Stores values in json comma separated fields.
I have already checked all results from https://stackoverflow.com/search?q=mysql+comma+separated+fields but none seems to solve my problem. I have checked on ways to restructure mysql schema but i would have too many tables to store the diseases diagnised from each patient. In addition one patient might be diagnosed with multiple diseases and a disease can be added any time. I might have almost 100 of them. If ID of Hypertension is 1 and arthritis is 2 a patient with both will have the
diseaseTreated field with "1","2" in the treatment table
Solution Expected--
I need to get reports for first time a specific disease has been treated for the first time or second time and more i.e revisit for treatment of the same disease (if i wanted to know how many cases of hypertension are for the first time, and how many cases of hypertension are recurrent)
Example - New cases report
Disease | New Cases
Hypertension | 4
Example - Recurrent cases report
Disease | New Cases
Hypertension | 1
Arthritis | 2
Am using Laravel I have attempted a lot of solutions but this is what i find too close to get what I need: Others I have attempted was looping through different array results i have queried from the database by using joins but I havent posted them because they have yielded nothing important.
$diseaseID
$countedDiseaseCases = DB::select('select * from treatmentTable where JSON_CONTAINS(diseases, \'[\"'.$diseaseID.'\"]\')')
This one would get me the rows with a specific disease and by using php count() on the result I get an int as 3 which is OK but I haven't got to put it as I expect filter and differentiate new and recurrent cases.
Thanks,
Any suggestion will be highly appreciated
If the deseaseTreated column is json, couldn't you add an isNew key and when the patient comes in for a second visit, flip that key to false or something similar?
Now when you want to make the report you can get counts on all of them.
//example deseaseTreated value
{
"deseases": [
{
"deseaseID":"Value",
"isNew":Boolean,
...
},
{...}
]
}
$records = DB::select('select * from treatment');
$diseases = DB::select('select * from diseases');
foreach ($diseases as $disease) {
$disease['count_new'] = 0;
}
foreach ($records as $record) {
$json = json_decode($record['diseaseTreated']);
foreach ($json['diseases'] as disease_index) {
if ($disease_index['isNew']) {
foreach ($diseases as &$d) {
if ($d['diseaseID'] == $disease_index['diseaseID']) {
$d['count_new']++;
}
}
}
}
I am trying to learn about Foreign keys and being able to associated data from one table to another. So I have a users table and a cards table.
The user table has 'user_id', 'username' & 'email'.
The card table has 'card_id' & 'name'.
what I am looking to do is associate a card form the card table to the users. so for example if the card table has Card1 inside and user1 wants that card (or more) assocaited with them how would I use the foreign key to do this.
Here is how I am selecting and showing my users at the moment:
<?php
$sql = "SELECT user_id, username, email_address FROM user";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
// output data of each row
while($row = $result->fetch_assoc()) {
echo
$row["username"] . "<br>",
$row["email_address"] . "<br><br>";
}
} else {
echo "0 Members";
}
$conn->close();
?>
I understand inside of the user table I will need to another another cell 'card_id' but not sure on which data type this should be?
Based on your question and on your following comment:
so the cards table is reffering to playing cards. A user can collect
the cards so they become a part of the users deck essentially. I want
a way for the card to be associated to the user.
I believe you can achieve that in 2 ways, depends on further scenarios in your game/script.
Scenario 1:
In case one card can be belong to only one user.
Add a new field to the cards table.
`user_id` INT(11)
When a user collect a card, just update that field so it will store the user's id.
Scenario 2:
In case one card can be belong to many users.
Create a new table called users_cards:
users_card
- id (INT)
- user_id (INT)
- cart_id (INT)
When a user collect a card, insert a new record to that table with both the card's id and the user's id.
I have two courses. In each course there are several assignments. A student can follow both courses.
I have the following tables:courses,student_courses,course1
My courses table has st_index,assignmnet_no,marks,course_no as the fields
and student_courses table has st_index,course1,course2 where 1is inserted if the student follows course1 or course2 .
Table course1 has Student_Index, Assignment1, Assignment2,Assignment3 as fields.
I have inserted my data into tables courses,student_courses. By retrieving data from these I want to come up with course1 table.course1
should look as follows:
Here's my code:
if($_SESSION['user']['course']=="Course1"){
$result=mysql_query("SELECT student_index FROM student_courses WHERE course1=1");
while($index=mysql_fetch_array($result)){
echo $index[0];
echo"<br>";
$result2=mysql_query("SELECT * FROM courses WHERE course_no='Course1' AND st_index='$index[0]'");
while($i2=mysql_fetch_array($result2)){
$ass_no=$i2['assignment_no'];
if($ass_no=='1'){
echo $index[0];
$result3=mysql_query("INSERT INTO course1(Student_Index,Assignment1) VALUES('$index[0]','$i2[marks]')");
}
if($ass_no=='2'){
echo $index[0];
$result4=mysql_query("INSERT INTO course1(Assignment2) VALUES('$i2[marks]')");
}
if($ass_no=='3'){
$result5=mysql_query("INSERT INTO course1(Assignment3) VALUES('$i2[marks]')");
}
}
}
}
?>
The problem is for course1 only the first student_index assignment values gets inserted. In there also for the same student_index the values gets inserted into two separate rows. What I am trying to do is when we consider a row in course1, which is identified by student_index that row should have all the assignment marks of that student. How can I achieve this?
That is say I have two records that match the conditions for the table course1 as 945,568.
In the course1 it only gets inserted records for 965 and it also looks like below. . The two rows should be one, under same index_no
In order to check what is going wrong inside first while loop I used echo $index[0] . It prints 945,568 both. But in the if statements inside the other while loop only 945 gets printed. That is when the loop is run for the second time I think the line $result2=mysql_query("SELECT * FROM courses WHERE course_no='Course1' AND st_index='$index[0]'"); doesn't get executed.
The problem is that in SQL, INSERT always adds a new row. You've inserted a row for each mark, but only provided a Student_Index for one of them (thus the empty indexes on subsequent rows). What you want is the UPDATE command.
So let's just use INSERT once to create a row for each student, just before the inner WHILE:
INSERT INTO course1(Student_Index) VALUES('$index[0]')
and then fill the fields by replacing your INSERT statements with (e.g. for assignment 1):
UPDATE course1 SET assignment1 = '$i2[marks]' WHERE Student_Index = '$index[0]'
Alternatively, you can accomplish this in SQL alone with the following:
CREATE TABLE course1
SELECT s1.st_index,
a1.marks AS Assignment1,
a2.marks AS Assignment2,
a3.marks AS Assignment3
FROM courses a1, courses a2, course a3
WHERE a1.course_no = 1
AND a2.course_no = 1
AND a3.course_no = 1
AND a1.assignment_no = 1
AND a2.assignment_no = 2
AND a3.assignment_no = 3
AND a1.st_index = a2.st_index
AND a1.st_index = a3.st_index;
We've joined the course table three times to select out the three rows where the three marks reside for with course_no=1 and constrained them to be the same student in all three rows. This will return one row for each student. Also, With this solution there is no need for a reference to the student_courses table at all since you can infer the enrollment of a student in a course by the presence of marks in the course table.
I am sorry for a verlo long question, just trying to explain in details. My formatting is not very good, sorry for that as well. I had a PHP/ MySQL App that essentially was not truly relational as I had one large table for all student scores. Among other things, I was able to calculate the average score for each subject, such that the average appeared alongside a student's score. Now I have since split the table up, to have a number of tables which I am successfully querying and creating School Report Cards as before. The hardship is that I can no longer calculate the avaerages for any subject.
Since I had one table with 5 subjects and each of the subjects had 2 tests, I queried for data and calculated the average as follows:
The one table (Columns):
id date name exam_no term term year eng_mid eng_end mat_mid mat_end phy_mid phy_end bio_mid bio_end che_mid che_end
The one query:
$query = "SELECT * FROM pupils_records2
WHERE grade='$grade' && class='$class' && year = '$year' && term ='$term'";
$result = mysqli_query($dbc, $query);
if (mysqli_num_rows($result) > 0) {
$num_rows=mysqli_num_rows($result);
while($row = mysqli_fetch_array($result)){
//English
$eng_pupils1{$row['fname']} = $row['eng_mid'];
$eng_pupils2{$row['fname']} = $row['eng_end'];
$mid=(array_values($eng_pupils1));
$end=(array_values($eng_pupils2));
$add = function($a, $b) { return $a + $b;};
$eng_total = array_map($add, $mid, $end);
foreach ($eng_total as $key => $value){
if ($value==''){
unset ($eng_total[$key]);
}
}
$eng_no=count($eng_total);
$eng_ave=array_sum($eng_total)/$eng_no;
$eng_ave=round($eng_ave,1);
//Mathematics
$mat_pupils1{$row['fname']} = $row['mat_mid'];
$mat_pupils2{$row['fname']} = $row['mat_end'];
$mid=(array_values($mat_pupils1));
$end=(array_values($mat_pupils2));
$add = function($a, $b) { return $a + $b;};
$mat_total = array_map($add, $mid, $end);
foreach ($mat_total as $key => $value){
if ($value==''){
unset ($mat_total[$key]);
}
}
print_r($mat_total);
$mat_no=count($mat_total);
echo '<br />';
print_r($mat_no);
$mat_ave=array_sum($mat_total)/$mat_no;
$mat_ave=round($mat_ave,1);
}
}
//Biology
etc
I split the table into separate tables and have names in a separate table, not needed for calculating avaerages, so I will not show it here. Each subject table tajkes the following form:
id date exam_no term year grade class test*
*Test would be eng_mid or eng_end or mat_mid etc.
Because I had only one query which returned 10 rows (5 subjects each with two tests: e.g. eng_mid (English Mit exam), eng_end (english end of term test), I was able to capture all rows in one call and pack each subject into an array, and then work out the class average, with the help of array_map. It may not be elegant, but it worked very well. Now, I have each test in it's own table.
I was trying to write a joint so as to get a signle resultset but the query fails. The columns as like:
I know that the database design is not anything to be proud off, but coming from a huge single table, this is a massive step (worthy a pat on the shoulder).
What I wish to do is to be able to query all my data and calculate class averages (about 30 students in each class). I tried to use separate queries but I ran into a wall, in that previously I would use the WHILE conditional as shown after the query for it to pull all rows and create an array from which I could get desired results. Now several queries just makes me confused as to how I can archieve the same results since a join is not working. Also I am having a separate $row variable, and that throws me further off balance!
Is it even possible to do averages as I did on my infamous one table (from the dark side) or is my table design so messed up, what I want just isn't humanly possible?
Please any help will be deeply appreciated.
Try using union. It would be something like
select grade, test from math
union all
select grade, test from english
union all
....
Also, in my opinion, better design would be to have table exams something like that (warning, pseudo-DML):
id int primary key,
student_id int foreign key students
subject_id int foreign key subjects
exam_type_id int foreign key exam_types
grade int(????)
exam_types table would be just midterm and final, but you'll be able to easily support more types in future, if required.
subjects table will store all kinds of subjects you have (at this time there will be only five of them: math, eng, phy, etc.
The averaging query would be as simple as (yes, you can actually do aggregation in the query itself)
select student_id, avg(grade)
from exams
group by student_id
i want to display record related to a specific primary key based on the foreign keys in other tables. How to display records for that primary key in other tables using php??
for example:
table1
primary key 1: plate#1
primary key 2: plate#2
primary key 3: plate#3
table2
primary key 1: destination|route|revenue|plate# 1
primary key 2: destination|route|revenue|plate# 3
table3
primary key 1: diesel price|number of liters|plate# 1
primary key 2: diesel price|number of liters|plate# 3
I already created a page that will display all the data in table1. I want to display the data in table1 and table2 that are related to the data in table1 when I made the database they already had relationship with each other. My problem is just displaying the record related to table1. I want to display records for just plate#1, another for plate#2 and so on.
Here's a crude example:
<?php
$truck_id = mysql_real_escape_string($_GET['truck_id']);
$sql_PK = "SELECT * FROM table1 WHERE id = '{$truck_id}'";
$res_PK = mysql_query($sql_PK);
$row_PK = mysql_fetch_assoc($res_PK);
$truck_plate = $row_PK['plate'];
$truck_plate = mysql_real_escape_string($truck_plate);
$sql = "SELECT table2.plate, table2.destination, table2.route, table3.plate, table3.diesel_price, table3.num_of_liters FROM table2, table3 WHERE table2.plate = table3.plate AND table2.plate = '{$truck_plate}'";
$res = mysql_query($sql) or die(mysql_error());
$row = mysql_fetch_array($res);
// this will give you the details from the following
//TABLE2
// plate
// destination
// route
//TABLE3
// plate
// diesel_price
// num_of_liters
?>
There's a couple of important things to remember. First is get in the habit of naming your fields without spaces in the database and use _ instead. so diesel price is diesel_price, etc. Secondly is to make sure that you are protecting yourself from any injections like I have shown here using the mysql_real_escape_string
So when someone clicks on truckdetails.php?plate=mrtchi it's going to query the database based on the plate number: mrtchi
You are probably looking to join tables to get the final results. Join allows you to essentially merge tables together and get a single result based on the selections. Google php mysql join table and look at some of the examples. Here's one for you: Join Tables