Codeigniter/ PHP MySQL Join - php

I have two tables: 'competitions' and 'entries'. On my competition table, I have a "completed" column that tells me if the competition has been run. On my entries table I have a user ID column and a competitions ID column. I am trying to create a JOIN in which I see if the user is able to compete by checking all the rows in the 'entries' table and then for each particular row checking if the corresponding competition ID is completed in the 'competitions' table. I'm not very strong with my joins and so far am slightly lost. This is what I have so far but it's not working properly:
$this->db->select('*');
$this->db->from('entries');
$this->db->join('competitions', 'competitions.id = entries.competition_id');
$this->db->where('entries.user_id', $user_id);
$this->db->where('competitions.complete', '0'); //0 for incomplete, 1 for complete
$query = $this->db->get();
if ($query->num_rows() > 0) {
return FALSE; //user is currently in an active competition
}else {
return TRUE; //user is not in an active competition
}
I am currently working in Codeigniter but an explanation in regular PHP would be fine also. Thanks so much for the help!

You may use left or right joins for better result you wish to get...
$this->db->join('table2','table1.id = table2.id','LEFT/RIGHT');
I thnk you can also use inner,outer joins...May hope it is useful

Related

Codeigniter Complex MySQL Query

I got two table which I would like to query from, which the users table and the user_job table
users table structure
user_job table
What I want to achieve is to write a MySQL query in CodeIgniter to display user information from users table if user_status in users table is "Active" And if there is no row in user_job table where user_job_status is equal to "On Probation" or user_job_status is equal to "Active"
In simple English, I want to display a user information if a user not currently on a job.
My current Codeigniter Model code is:
//get all user that are not currently assigned to a position
function get_idle_user(){
$this->db->select('*');
$this->db->from('users');
$this->db->join('user_job', 'user_job.user_id_fk = users.user_id', 'INNER');
$this->db->where('users.user_status','Active');
$this->db->where("(user_job.user_job_status != 'Active' OR user_job.user_job_status != 'On Probation')", NULL, FALSE);
$this->db->group_by('users.user_id');
if($query = $this->db->get()){
return $query;
}else{
return false;
}
}
The problem with this code that it will still display user information if there is a row related to a user and user_job_status does not satisfy the where condition above.
Please Help.
I believe this is what you are after ...
$db->select('user_id_fk,COUNT(*) as `Tally`');
$db->where('user_job_status','On Probabtion');
$db->or_where('user_job_status','Active');
$db->group_by('user_id_fk');
$sub = $db->get_compiled_select('user_job_table');
$db->join("($sub) ujt",'ujt.user_id_fk = users.user_id AND Tally = 0','left');
$db->where('user_status','Active');
// View this query in full
//echo $db->get_compiled_select('users_table');
// Get the data
$data = $db->get('users_table')->result_array();
Note:
You don't need select('*') - it isn't needed
You don't need ->from() - it can be used in the get() element
I have left in the get_compiled_select which will allow you to see the full query and get an idea what its doing. You should comment out the $data line if you uncomment the echo line.
What this query is doing is saying get all users from the job_table which don't have the status Active or On Probation and a list of User ID's. That way you can then get Active users from the users_table and users with a tally of 0.

Grocery Crud - Can't differentiate attribute in returning query table

I've been using Grocery Crud to develop a simple local application that allows users to register themselves and like bands and rate them and select people they know that are also registered in the application.
Entities:
Person(person_id,person_URL, fullname, hometown)
Band(band_id,band_URL,band_name,country,genre)
Relationships:
Likes(person_id,band_id,rate)
Knows(person_id,known_person_id)
My questions are:
1) I want to return a table of person and known person like below:
KNOWS
person_id | fullname | known_person_id | known_fullname
but I can't use *set_relation_n_n* function 'cause the relationship is (Person -> Likes -> Person), so it's giving me error. The other solution I came up with is making a custom table making a query to return the values I want and show it in the table (code below). The custom table returned is correct but when I render it to my Grocery Crud table, I need to specify $crud->columns('person_id', 'fullname', 'known_person_id', 'fullname'), and it cannot differentiate the fullname of the person and the fullname of the known person. How would I make it in order to be able to show the table that way?
2) I have the same issue in another table but could manage that using the function *set_relation_n_n* 'cause it's a relationship (Person -> Likes -> Band), so since it's 2 different entities it didn't return me a error. The problem is that the query (code below) returns me the whole table and I want only 25 records per page. When I try to use "LIMIT 25" in the query, it returns me ONLY 25 records and the "next page" button doesn't work. Any solutions?
Below, all the information:
CODE for question 1:
function knows_management()
{
$crud = new grocery_CRUD();
$crud->set_model('model_socialnetwork');
$crud->set_table('knows');
$crud->set_subject('Known');
$crud->basic_model->set_query_str('SELECT tb1.person_id, tb1.fullname, tb1.known_person_id, person.fullname FROM (SELECT person.person_id, person.fullname, knows.known_person_id FROM person INNER JOIN knows ON person.person_id = knows.person_id) tb1 INNER JOIN person ON tb1.known_person_id = person.person_id');<br>
$crud->columns('person_id','fullname','known_person_id','fullname');
$output = $crud->render();
$this->_socialnetwork_output($output);
}
CODE for question 2:
function likes_management()
{
$crud = new grocery_CRUD();
$crud->set_model('model_socialnetwork');
$crud->set_table('likes');
$crud->set_subject('Like');
$crud->columns('person_id','fullname','band_id','band_name', 'rate');
$crud->basic_model->set_query_str('SELECT tb2.person_id, tb2.fullname, tb2.band_id, band.band_name, tb2.rate FROM(SELECT tb1.person_id, person.fullname, tb1.band_id, tb1.rate FROM(SELECT person.person_id, likes.band_id, likes.rate FROM person INNER JOIN likes ON person.person_id = likes.person_id) tb1 INNER JOIN person ON tb1.person_id = person.person_id) tb2 INNER JOIN band ON tb2.band_id = band.band_id');
$output = $crud->render();
$this->_socialnetwork_output($output);
}
Question 1) What if you use an alias name in your query, for example
SELECT tb1.person_id, tb1.fullname as Tb1fullName, tb1.known_person_id, person.fullname as PersonFullName
Question 2) I would not recommend you to add LIMIT directly / manually in your query. In the file application/config/grocery_crud.php, you have two options directly related to pagination
You should use and configure them properly
// The default per page when a user firstly see a list page
$config['grocery_crud_default_per_page'] = 25;
....
//Having some options at the list paging. This is the default one that all the websites are using.
//Make sure that the number of grocery_crud_default_per_page variable is included to this array.
$config['grocery_crud_paging_options'] = array('10','25','50','100');

Delete one column from table, Update another with PHP MYSQL

I have two tables. One table is the matches table (e2wedstrijden) and another table is my scoring table with the points earned etc. (e2teams).
Now I have that I can delete a match from the e2wedstrijden table. And this is working fine.
But I want that if I delete a match from that table. It also add or decrease points to the table ("e2teams"). I tried to compare the tables but this is not working.
So I want for example:
If($row['thuisscore'] == $row['uitscore']) what are to row names in my e2wedstrijden table. So if these two are the same (like 0-0 or 1-1 or something) Than it needs to decrease 1 point from the table e2teams. But only by the teams that are the same as the rows "Thuisteam" and "Uitteam" in my e2wedstrijden table. So the Row Thuisteam (in "e2wedstrijden") Needs to find the same result in ("e2teams") row Team. And this needs to be done the same with the Row Uitteam (in "e2wedstrijden") Needs to find the same result in ("e2teams")
Thuisteam and Uitteam = Dutch for hometeam and awayteam. I think my fault is that the system can't link the 'Thuisteam' from e2wedstrijden to the Team in e2teams but don't know how to solve it
This is my deletematches.php, It deletes the match but doesn't decrease or adds points:
<?php
if(!isset($_COOKIE['E2ingelogd'])) {
header("location:../../index.php");
}
include "../../connect.php";
$dbhandle = mysql_connect($hostname, $username, $password) or die("Could not connect to database");
$selected = mysql_select_db("login", $dbhandle);
$result = mysql_query("SELECT * FROM e2wedstrijden WHERE ID = ".$_GET['del']."");
while($row = mysql_fetch_assoc($result)){
if( $row['thuisscore'] == $row['uitscore']){
echo $row['thuisscore'];
mysql_query("UPDATE e2teams SET Punten = Punten-1 WHERE Team ='".$row['Thuisteam']."'");
mysql_query("UPDATE e2teams SET Gespeeld = Gespeeld-1 WHERE Team = ('".$row['Thuisteam']."'");
mysql_query("UPDATE e2teams SET Verloren = Gelijk-1 WHERE Team ='".$row['Uitteam']."'");
echo "Team is deleted";
}else{
echo 'Update Error!';
}
}
$table_1_delete = mysql_query("DELETE FROM e2wedstrijden WHERE ID = ".$_GET['del']."");
?>
This is my e2teams table:
And this is my E2wedstrijden table:
So i need something like:
UPDATE e2teams SET Punten = Punten-1 WHERE Team = Look in table ("e2wedstrijden) deleted Thuisteam and deleted Uitteam
Hope you can help
You've placed an extra parentheses in the 2nd query for "gespeeld" right after the equal sign:
mysql_query("UPDATE e2teams SET Gespeeld = Gespeeld-1
WHERE Team = ('".$row['Thuisteam']."'");
Is this what isn't updating?
Without being 100% sure on how your data model works, it might make sense at refactoring what you have. Something that might be useful would be to create a view of the summary table and just update the data from the child/master table.... aggregating in the view layer. Views in mysql can be seen here.
If you are stuck with the data model you have (legacy application, etc.) you can possibly look at triggers if you have to modify data in two tables you might want to consider stored procedures or triggers, discussed here and here.
The third thing that comes to mind, is around correlated sub-queries and how you could reference the another table in a sort of update-from. However, you're ID's aren't surrogate keys in this situation.
Also, have a look at sql injection; I haven't looked at PHP in a while but those sql statements kind of look like they are created with sting composition
Good luck,

Laravel eloquent efficiency

I have a Laravel 4 app with three tables in question: a client table, an order table with client_id column, and an order_outputs table with an order_id column.
My question is whether the following code is efficient enough for what I'm trying to do, which is find whether the logged in user has ordered a specific output_id . Best practices would be highly appreciated.
public function getEdit($id) {
$order = ShopOrder::find($id);
$client = ShopClient::find($order->client_id);
$clientorders = ShopOrder::where('client_id', $client->id)->get();
$orderlist =array();
foreach ($clientorders as $co)
{
$orderlist[] =($co->id);
}
$orderoutputs = ShopOrderoutput::whereIn('order_id',$orderlist)->where('output_id', '22')->get();
$orderoutputslist = array();
foreach ($orderoutputs as $list)
{
$orderoutputslist[] = $list->output_id;
}
if (in_array(22, $orderoutputslist))
{
echo 'finally';
}
}
Thanks.
If all you want to do is find out whether the user has an order with a specific output_id, I would combine the queries into one Joined query.
I assume that the order_outputs table is related to the order_outputs table, by a foreign key order_id.
I am also assuming that you are trying to find if the client/user has ever had an order with order_output output_id = 22
I'm not familiar with the syntax for the db queries in laravel.
In plain SQL this would be.
SELECT id FROM orders
INNER JOIN order_output ON order.id = order_output.order_id
INNER JOIN clients on order.client_id = client.id
WHERE client.id = $client_id
AND order_output.output_id = 22;
Then count your result set and see if there is at least one.
This way your database engine will do the work for you instead of your php code having to loop through result sets.

codeigniter select distinct function not working

I have a table with this structure:
opinion_id, author_id, title, content
I would like to get all the latest records from the table, one record for author, that means the latest record for every author...
My distinct function does not seem to be working...
function getOpinions() {
$data = array();
$this->db->select('*');
$this->db->from('opinions');
$this->db->join('authors', 'opinions.author_id = authors.author_id');
$this->db->order_by('date', 'desc');
$this->db->distinct('author_id');
$Q = $this->db->get();
if ($Q->num_rows() > 0) {
foreach($Q->result_array() as $row) {
$data[] = $row;
}
}
$Q->free_result();
return $data;
}
In Codeigniter, distinct does not work the way you expect it by field name. If you look at the manual - there is no argument for distinct. If you look at the code, it only takes a boolean, which defaults to true. It just adds the DISTINCT keyword to the query after the SELECT keyword. That's it.
In your case, I think it would be better to use a GROUP BY as in
$this->db->group_by('opinions.author_id');
Hopefully the order by would work as per your need in this instance by ordering before the grouping.
Cheers!
EDIT - update after OP comments
I know the ordering can be messed up - I sort of mentioned it :)
Anyway, I might be assuming some of your table structure here, but this would force the GROUP BY to pick the rows on the top. I assume that the date is on the opinions table and you only want the latest row from that with author details.
SELECT * FROM `authors`
JOIN (
SELECT * FROM opinions
ORDER BY `date` DESC
) AS ops ON ops.author_id = authors.author_id
GROUP BY ops.author_id
You will not be able to construct this query on active record though. Hope this helps.

Categories