I have two tables with following costruction:
errortype:
| id | errortype_text |
errorreason:
| id | errorreason_text | errortype_id |
I would like to select all data from errorreason table and replace the errortype_id data with the coresponding errortype_text.
How is this possible?
if the tables have a foreign key you can do that in your model:
$this->db->select('erroreason_text');
$this->db->join('errorreason', 'errortype.id = errorreason.id');
$query = $this->db->get('errortype');
return $query->result();
If you are talking about SQL/MySQL it should be:
SELECT `errortype_text`, `errorreason_text`, `errortype_id` FROM `errorreason` JOIN `errortype` ON `errortype`.`id`=`errorreason`.`id`
This joins your tables based on entries having the same id and it is exactly the method Yan suggested.
If you are explicitely referring to PHP/Codeigniter, you have to pass this as a parameter to mysql_query to be afterwards evaluated:
$query=mysql_query("SELECT `errortype_text`, `errorreason_text`, `errortype_id` FROM `errorreason` JOIN `errortype` ON `errortype`.`id`=`errorreason`.`id`");
Related
I'm having a problem at the moment where I have a column called rating in the links table and there is definitely values other than 0 within the column but 0 is the only value which is returned foreach link. When I do a simple get for that column it then shows all the other values but not when I do an SQL Join.
I know the problem is my joining of the tables but I'm unsure how I would go about joining these specific tables.
Database Table Structure
The rating column is the one which is causing me problems.
'links' id | title | url | user_id | list_id | rating | weight | date_created
'list' id | list_title | list_description | user_id | rating | views | date_created
'link_ratings' id | user_id | link_id | rated | date_created
Model:
public function get_latest(){
$this->db->limit(100);
$this->db->order_by('links.date_created', 'DESC');
$this->db->select('*');
$this->db->select('links.id as current_link_id');
$this->db->from('links');
$this->db->join('list', 'links.list_id = list.id');
$this->db->join('users', 'links.user_id = users.id');
$this->db->join('link_ratings', 'links.id = link_ratings.link_id','left');
$get_latest = $this->db->get();
return $get_latest;
}
Any Help is appreciated.
You should try this:
function get_latest(){
$this->db->select('list.*, users.*, links.id as current_link_id');
$this->db->from('links');
$this->db->join('list', 'links.list_id = list.id');
$this->db->join('users', 'links.user_id = users.id');
$this->db->join('link_ratings', 'links.id = link_ratings.link_id','left');
$this->db->order_by('links.date_created', 'DESC');
$this->db->limit(100);
$get_latest = $this->db->get()->result_array(); #fetch all rows here
echo "<pre>";print_r( $get_latest );die; #print all rows and see if its fetching ratings corrctly or not.
echo $this->db->last_query();die; #check the query generated
return $get_latest;
}
The reason will be purely logical, in that the join will be causing no results to be returned because there are no results. I've fallen into this many times.
I am not able to diagnose your particular problem but when faced with issues like this I:
1- turn on the CI profiler
2- var_dump the array so you can see what's going on
3- write a traditional SQL query and run it in PHPMyAdmin
One, or a combination of all three, will enable you to diagnose.
I am trying to get a single record for one table by checking for a variable that is in two associated tables.
For instance my tables are
user:
id | name
3781 | Foo Manchu
user_programs:
id | user_id | page_id
4150 | 3781 | 16974
Page
id | title | section_id
16974 | Dudes | 3
So I need to query and return the Users who have a section_id of 3
Users are associated to the user_program table which are assocaited to specific pages through page_id.
This is what I have which is not returning anything:
if($section_id == 3) {
$q = $this->createQuery('u');
$q->leftJoin('u.user_programs up');
$q->leftJoin('up.Page p');
$q->where('u.published=1 AND u.is_preview = 0 AND u.featured=1 AND fp.deleted_at IS NULL');
$q->addWhere('p.section_id=?', $section_id);
$q->orderBy('RAND()')->limit(1);
I can succesfully return the u query without doing the join, but I need to limit the query to only return users with a section_id on the associated page of 3.
If the schema is correct, then a User should have a Pages (or something like that) relation. You can write the query like this:
$query = $this->createQuery('u')
->innerJoin('u.Pages p')
->andWhere('u.published = ?', 1)
->andWhere('u.is_preview = ?', 0)
->andWhere('u.featured = ?', 1)
->addWhere('p.section_id = ?', $section_id)
->limit(1)
;
I removed the fp.deleted_at part as it makes no sense when using SoftDelete (I presume you use that) and the fp alias was not in the original query anyway.
I need to sum the totals of a row except the first column.
Something similar too:
SELECT SUM( col2 + col3 + col4 +colN)
FROM numbers
WHERE user_name = 'person';
My table will continuously have columns added to it. So I want it to automatically pick up the sum of the new columns too without it needing to be hard coded into the query?
user_name | Col | col2 | Col3 | Col4 + other columns.
person1 | 2 | 3 | 76 | 56 etc. ---------> sum of row
person2 | 6 | 72 | 200 | 13 etc. ---------> sum of row
Thanks in advance for any help!
Not wishing to 'avoid' the question, but it looks like you could do with having a different data structure.
You should consider having a 'users' table with columns for id and user_name, and a new table (e.g. properties) with a row for each of the other columns in your current table (Col1, Col2 ... ColN). The new table would then have a column for user_name to link it to the users table.
That way you'd be able to do something like:
SELECT SUM(property_column) FROM properties WHERE user_name = <RequiredUserName>
I'd also recommend selecting users by ID (i.e. have the properties table with a user_id column, rather than a user_name column), unless you're confident that a user_name is never going to change (and even then...).
Maybe the easiest solution is to do it in PHP:
$res = mysql_query("select * from numbers where user = ...");
while ($row = mysql_fetch_assoc($res)) {
$row['Id'] = 0; // don't want to sum the Id
$sum = array_sum($row); // this is the required sum
....
}
As stated you would be better advised revisiting your database structure,
If you can't and
If you want to do it in PHP you can get the resultset back and then loop through the fields and exclude the fields you don't want then add up everything else, assuming it is of the right type, use mysql_field_type to find those of a specific type.
I am just getting started in learning how to do INNER JOINS correctly and I can't think of the best/easiest way to do this.
I am building a url shortener and I am trying to build a query that will get all long_url.destination's matching a slug "test". One slug might point to multiple long_url.destination's(URL shuffling, GEO matching, etc...). So I need the slug to get all long_url.destination's with the same short_url.slug.
Before I was running another query to get the short_id from the slug, then running another query to select all rows in long_url that had a matching short_id.
I think it might be quicker if I use an inner join, but I am unsure how to properly set it up.
I want to get all destination columns in table long_url with only the slug data in short_url without having to run a separate query to get the short_id from the slug.
Table: short_url
Columns: short_id | slug | enabled | timestamp
example: 1 test 1 1323343922
Table: long_url
Columns: long_id | short_id | destination | geo | enabled | timestamp
example: 1 1 http://www.test.com US 1 132334922
example: 2 1 http://www.test.co.uk UK 1 132334922
I got this so far:
SELECT destination, geo FROM long_url INNER JOIN short_url
ON long_url.short_id = short_url.short_id WHERE enabled = 1;
function get_long_urls($slug) {
$query = "SELECT....";
$stmt = $db->prepare($query);
$stmt->execute(array(':slug' => $slug));
$results = $stmt->fetchAll(PDO::FETCH_ASSOC);
return (array) $results:
}
example $results = array(
'http://www.test.com' => 'US',
'http://www.test.co.uk' => 'UK',
);
Thanks for any help.
select long_url.destination
, long_url.geo
from long_url
inner
join short_url
on long_url.short_id = short_url.short_id
where short_url.slug = :slug
and long_url.enabled = 1
You don't need to qualify all column names like I did, because in this particular query there wasn't any ambiguity. All I really did is add a bound parameter placeholder.
SELECT destination, geo FROM long_url LEFT JOIN short_url
ON (long_url.short_id = short_url.short_id) WHERE enabled = 1
i have 3 tables that looks like this:
game_table
+---------+------------+------------+----------------------+----------+
| game_id | game_title | sponser_id | game expiration date | prize_id |
+---------+------------+------------+----------------------+----------+
prize_table
+----------+---------------------------+------------+-------------+--------------------+--------------------------------------------+
| prize_id | prize_image_name | prize_cost | prize_title | remaining_quantity | prize_description |
+----------+---------------------------+------------+-------------+--------------------+--------------------------------------------+
sponser_table
+------------+--------------+
| sponser_id | sponser_name |
+------------+--------------+
how do i build query that select all data from the 3 tables that
meat the statement that go's something like pseudo code:
select all data from game_table and prize_table and sponser_table where game_table.sponser_id = 2 and game_table.prize_id = 2
i tried something like this :
SELECT game_list.*, prize_list.* ,sponser_list.* FROM game_list, prize_list,sponser_list
WHERE game_list.sponser_id=2 And game_list.prize_id = 2 And game_list.game_id=2 ;
but it gave me no good results .
You had a WHERE clause to limit to the correct ids, but you had no join conditions to relate your tables. Instead of the implicit join syntax you attempted (comma-separated table list), use a explicit JOINs with stated relating columns:
SELECT
game_list.*,
prize_list.* ,
sponser_list.*
FROM
game_list
JOIN prize_list ON game_list.prize_id = prize_list.prize_id
JOIN sponser_list ON game_list.sponser_id = sponser_list.sponser_id
WHERE game_list.sponser_id=2 And game_list.prize_id = 2 And game_list.game_id=2 ;
I would recommend against selecting all columns from each table though, since you are duplicating the id columns in at least two places. Instead, be explicit about the columns you want. This will also help you if you later add additional columns to these tables that should not be included in this query.
SELECT
game_id,
game_title,
game_list.sponser_id,
game_expiration_date,
game_list.prize_id,
prize_image_name,
prize_cost,
prize_title,
remaining_quantity,
prize_description,
sponser_name
FROM
game_list
JOIN prize_list ON game_list.prize_id = prize_list.prize_id
JOIN sponser_list ON game_list.sponser_id = sponser_list.sponser_id
WHERE game_list.sponser_id=2 And game_list.prize_id = 2 And game_list.game_id=2 ;
SELECT *
FROM game_table
JOIN prize_table USING (prize_id)
JOIN sponser_table USING (sponser_id)
WHERE sponser_id = 2
AND prize_id = 2
AND game_id = 2
SELECT
game_list.*, prize_list.* ,sponser_list.*
FROM game_list
JOIN prize_list ON game_list.prize_id = prize_list.prize_id
JOIN sponser_list ON game_list.sponser_id = sponser_list.sponser_id
WHERE
game_list.sponser_id=2 And game_list.prize_id = 2 And game_list.game_id=2 ;
From your description it appears that the tables may be related. If they are, you need to use a join, like this:
SELECT *
FROM game_table g
LEFT OUTER JOIN prize_table p ON p.prize_id=g.prize_id
LEFT OUTER JOIN sponser_table s ON s.sponser_id=g.sponser_id
WHERE g.game_id=2