Good Day!
Is it possible to apply if condition in the query in codeigniter: model?
I have this query in Model:
function activity($id) {
$this->db->select('a.ID, a.activityID, r.roleName');
$this->db->from('activity a');
$this->db->join('role r', 'r.ID = a.activityID');
$this->db->where('a.ID', $id);
$query = $this->db->get();
return $query->result_array();
}
And in my view I want to show the ID and activityID from table activity and also the counter part roleName (from table role) of activityID.
But the tricky part is that the value in activityID is not just a simple INT, like this:
ID ActivityID
1 5,7,9
2 2,4
3
4 10
5 1,6
So I'm thinking to use if condition in the query, like if the activityID value not contains comma (,) it will use join like this: $this->db->join('role r', 'r.ID = a.activityID'); then get the r.roleName.
Example:
ID ActivityID Role Name
4 10 Basketball
But if contains comma (,), it will explode by comma (,) then join like this: $this->db->join('role r', 'r.ID = a.activityID'); but it will output also by roleName with comma in between.
Example:
ID ActivityID Role Name
1 5,7,9 Tennis,Football,Soccer
2 2,4 Volleyball,Chess
Can someone help me with this?
Thanks in advance.
This is very bad idea to have comma separated ids in your column you should first normalize your structure other wise it will lead you more expensive problems,for now you use FIND_IN_SET() ,for having role names also as comma separated you can use GROUP_CONCAT
Be ware of that fact it has a default limit of 1024 characters to concat but it can be increased which is defined in manual
SELECT
a.ID,
GROUP_CONCAT(a.activityID) activityID,
GROUP_CONCAT(r.roleName) roleName
FROM activity a
LEFT JOIN `role` r ON(FIND_IN_SET(r.ID,a.activityID) > 0);
WHERE a.ID = $id
GROUP BY a.ID
For CI use query() function for above query
Please first have a look at Database Normalization
Related
I have two tables first and second.
first Table:
ID NAME ADDRESS
1 test testing address
2 test1 testing address
3 test2 testing address
4 test3 testing address
second Table:
T_ID Partner_id date
1 2 12345678
3 4 32164584
If input T_id is given. Then corresponding Partner_id is taken and it is compared with the ID from first table and corresponding row should be selected.
Can you please tell me.
In php I can write this with two queries but I want it to be in a single query.
Queries in php:
$q=mysqli_query($conn, "SELECT Partner_id from second where T_ID=1");
$qa=mysqli_fetch_array($q);
$w=mysqli_query($conn, "SELECT * from first where ID=$qa[0]");
But, how to combine this two statements?
The specified result can be returned using a query with a join operation.
SELECT f.*
FROM first f
JOIN second s
ON s.Partner_id = f.ID
WHERE s.T_ID=1
Note that there is a potential for this to return more rows that the original, if the first query returns more than one row. (That is, we don't assume that T_ID is unique in second, or that every row with a given T_ID value will have identical values for Partner_id.)
There are other query patterns that will return an equivalent result, but the join operation is the normative pattern.
try to use union ,see this this link
where The SQL UNION operator combines the result of two or more SELECT statements.
SELECT * FROM first WHERE ID IN( SELECT Parent_id FROM second WHERE T_ID = 1 )
or
SELECT * FROM first WHERE ID = ( SELECT Parent_id FROM second WHERE T_ID = 1 )
SELECT * FORM first_table AS f
JOIN second_table AS s
ON s.parent_id =f.id
WHERE s.T_ID = $id
Working on a project with CodeIgniter and Active Record.
I face an issue with a query :
I have 3 tables in my database which I would like not only to join but also to make countS on 2 of them. The tables are respectively linked with user_id, store_user_id, event_user_id fields
Table 1 : user
user_id
Table 2 : store
store_user_id
Table 3 : event
event_user_id
What I am trying to do is to :
1 - Get all the data from user
2 - Count the number of stores with store_user_id = user_id (it may be 0)
3 - Count the number of events with event_user_id = user_id (it may be 0)
I have done this in my function :
$this->db->select('*');
$this->db->select('COUNT(s.store_user_id) as total_store', FALSE);
$this->db->select('COUNT(e.event_user_id) as total_event', FALSE);
$this->db->from('user u');
$this->db->join('store s', 's.store_user_id = u.user_id', 'left'); // this joins the user table to store table
$this->db->join('event e', 'e.event_user_id = u.user_id', 'left'); // this joins the user table to event table
$this->db->group_by('u.user_id');
$q = $this->db->get();
if ($q->num_rows()>0){
foreach ($q->result() as $rows) {
$data[] = $rows;
}
return $data;
}
The trouble is that when I display total_store and total_event in my view, the results are the same and I think figures are multiplied between them..
For example :
For an user I have 3 events en 4 stores, the results displayed will be total_event = total_store = 12 ...
I don't understand why and it makes me crazy for hours!! Moreover, when I make only one count, the result is correct..
Any idea??
Many thanks in advance :)
Lastly I have implemented this basic SQL query :
$this->db->query('SELECT
u.*,
x.total_store,
y.total_event
FROM
user u
LEFT OUTER JOIN (SELECT s.store_user_id, COUNT(s.store_user_id) AS total_store
FROM store s
GROUP BY s.store_user_id) x ON x.store_user_id = u.user_id
LEFT OUTER JOIN (SELECT e.event_user_id, COUNT(e.event_user_id) AS total_event
FROM event e
GROUP BY e.event_user_id) y ON y.event_user_id = u.user_id
');
Hope it will helps others
When you count() you're counting the number of rows, not the number of distinct values in the result set. You're right that the number is being multiplied: there's a row in your resultset for each user-store-event combination.
My problem is that I have a query that with group_concat gets me the result I need. this is the query. And I have already joined 3 tables where table1 has for example people names, table2 has their liked fruit info and table3 has their fruit names. In table2 they are numbered cause of for the need to alter the data for needs
SELECT
table1.row2,
table2.group_concat(distinct row2)
FROM table1
JOIN table2
WHERE
table1.row1=table2.row1
GROUP BY
table1.row1
The issue is that row 2 gives out numbers (example 1,2) but they are defined in another table into 1=apple and 2=orange
So i use a function with defines that
function fruit($value){
if ($value==1){
$result=apple;
}elseif($value==2){
$result=orange;
}
return $result;
}
So as i want to have a column where instead of "1,2" is "apple, orange" I use the function in the fetching results. Issue is that i dont get "apple,orange", instead I get "apple"
Seems like it just zeros my grouping
Looked for answers but couldnt find any. anybody ???
You can join onto this other table to get the names in the query:
SELECT row1,group_concat(distinct table2.name) FROM table
LEFT JOIN table2 ON (table.row2 = table2.id)
GROUP by row1
Obviously you'll need to change table2.id and table2.name to something appropriate.
As for the function you aren't returning $result so any calls to this will return NULL. Simply add:
return $result;
I'm very new with SQL and need assistance on how I can accomplish this task using the correct query.
I have 2 tables that I need to use. Table "TB1" has:
id Name
1 bob
2 blow
3 joe
table "TB2" has:
compid property
1 bob
2 blow
I am trying to get which compid is missing in "TB2" and insert it from "TB1"
the query I am doing is:
SELECT id, name from TB1, TB2 where id <> compid
what I get is 2 ouputs of Id 1, and 2, and 3 outputs from id 3. by using php:
for($i=0;$i <= mysql_num_rows($comp)-1; $i++)
{
echo mysql_result($comp, $i, 0)."<br>";
}
and I expected the ouput 3 but instead got this:
1
1
2
2
3
3
3
I understand its comparing all the rows within the table but is there a way to achieve what I am looking for?
Thanks for your time.
You are performing an implicit Cartesian JOIN which results in every row against every other row. You need to specify what attribute JOINs the two tables.
Using implicit syntax (not recommended):
SELECT id, name
FROM TB1, TB2
WHERE id <> compid
AND TB1.Name = TB2.property <-- Column join
Using explicit syntax:
SELECT id, name
FROM TB1
JOIN TB2
ON TB2.property = TB1.Name <-- Column join
WHERE id <> compid
To accomplish your goal you would need something along the lines of:
SELECT TB1.id, TB1.name
FROM TB1
LEFT JOIN TB2
ON TB2.property = TB1.Name
WHERE TB2.compid IS NULL
See it in action
It's best practice to always alias the columns you select to prevent ambiguity.
To select it you can do:
SELECT *
FROM TB1
WHERE id NOT IN (
SELECT compid
FROM TB2
);
I have two tables, Table A and Table B. For each record in table A there are many records in Table B; thus, a one to many relationship exists between tables A and B. I want to perform a query so that for each row returned from table A, all of the corresponding rows will be returned from table B. From what I understand I'll need to use a INNER Join - however, how would I go about accessing all of the returned rows through say, PHP?
$sql = "Select A.ID, B.Name * From A INNER JOIN B ON A.ID = B.ID";
A.ID | B.fName | B.lName
1 nameone lnameone
1 nametwo lnametwo
2 namethree lnamethree
4 namefour lnamefour
Now that I have the above results, I want to use PHP to loop through all of the values of B.Name only for a single A.ID at a time. So, the results I want would look like:
1.
nameOne lNameOne
nameTwo lnametwo
2. namethree lNamethree
4. nameFour lNameFour
Basically, I'm trying to group the query results by the ID in table A.
I appreciate the help very much!
Thank you,
Evan
You could just Google "php get from database," and use some normal array pre-processing, but I worry the advice you find may not be ideal. Here's what I'd do:
$pdo = new PDO('mysql:host=host;dbname=dbname', 'user', 'pass');
$result = $pdo->query(<<<SQL
SELECT
ID,
Name
FROM
A
-- Alternative to `JOIN B USING(ID)` or `JOIN B ON (A.ID = B.ID)
NATURAL JOIN B
SQL
);
$a = array();
while ($row = $result->fetch()) {
if (!isset($a[$row['ID']]) {
$a[$row['ID']] = array();
}
$a[$row['ID']][] = $row['Name'];
}
You could also GROUP BY the ID and GROUP_CONCAT the names to be exploded in PHP later to skip the manual array creation and reduce some iteration (although SQL will do more in that case).
Adding a simple ORDER BY A.ID to the SQL query would probably get you quite far in "grouping" the items together. It's difficult to give a more detailed answer without knowing exactly what you want to do with the "groups".