Join table using two columns of the tables - php

i have mysql query
SELECT `users`.`user_id`, `tool`.`name` FROM `users` LEFT JOIN
`project` ON
`users`.`user_id` = `project`.`user_id` LEFT JOIN `tools` ON `users`.'user_id' = `tools`.`user_id` AND `project`.`project_id` = `tools`.`project_id`
Where project_id = value
and user_id = value
and my doctrine query is this
$query = $queryBuilder->select ( array (
'user.userId',
'user.name',
))
->from('Users', 'users')
->leftJoin(user.project, project)
->leftJoin(user.tool, tool)
->where(user.userId = value)
->andWhere(project.projectId = value)
now how would i include the AND project.project_id = tools.`project_id
part to Doctrine query builder
without

Related

Combine MySQL SELECT queries with IF statement

I want to combine my two SELECT statements with an if statement. Currently I am just getting the row and then doing if($row['activated'] === 1) { ... run 2nd select statement }.
There has to be a better and much faster way of doing it (performance-wise). This is what I'm trying to do:
For example: (1st SELECT statement)
$db = $stmt->("SELECT * FROM users WHERE id = :id AND activated = 1");
$db->bindParam(':id', $id);
$db->execute();
If that above SELECT statement is true, then do this: (2nd SELECT statement)
$db = $stmt->("SELECT * FROM user_settings WHERE user_id = :user_id");
$db->bindParam(':user_id', $id);
$db->execute();
How can I combine those two SELECT statements? If it is else or if activated = 0, then only do the first select.
Bonus question:
How can I make it three If statements? For example, the 2nd SELECT statement will be like this:
$db = $stmt->("SELECT * FROM user_settings WHERE user_id = :user_id AND color = :color");
$db->bindParam(':user_id', $id);
$db->bindParam(':color', $color);
$db->execute();
Now if that statement is true, run this 3rd SELECT statement:
$db = $stmt->("SELECT * FROM friends WHERE user_id = :user_id");
$db->bindParam(':user_id', $id);
$db->execute();
You can merge/combine
SELECT * FROM user_settings WHERE user_id = :user_id AND color = :color
and
SELECT * FROM friends WHERE user_id = :user_id
Into one query with a JOIN
SELECT
*
FROM
user_settings
INNER JOIN
friends
ON
user_settings.user_id = friends.user_id
AND
user_settings.color = :color
Or a other JOIN format
SELECT
*
FROM
user_settings
INNER JOIN
friends
ON
user_settings.user_id = friends.user_id
WHERE
user_settings.color = :color
Or you can write it as this JOIN. (most likely slower)
SELECT
*
FROM (
SELECT
*
FROM
user_settings
WHERE
user_settings.color = :color
) AS user_settings
INNER JOIN
friends
ON
user_settings.user_id = friends.user_id
The used method which is best/faster can/will be depending which indexes you have in use.

Php query regarding 2 FK and 1 Primary Key

In my table internships, I have two foreign keys id_promoter_internship and id_supervisor_internship. In the table business_contacts I have 1 primary key id_business. I'm trying to get data from the business_contacts table which is linked to the internships table. Is the following query correct?
public function update_form_business_contact($name_enterprise){
$query = "
SELECT
*
FROM business_contacts
,internships
WHERE
business_contacts.id_business = internships.id_supervisor_internship
AND internships.name_enterprise_internship = '$name_enterprise'";
$result = $this->_db->query($query);
# Go through results of teachers
if($result->rowCount()!=0){
while($row=$result->fetch()){
$contact= new businesscontact ( $row->id_business,$row->firstname_business,$row->lastname_business,$row->service_business,$row->function_business,$row->phone_business,$row->phone_secretary_business,$row->mobile_business);
}
}
return $contact;
}
My question is: Does the primary key have to reference both foreign keys? If so how would I do that.
Thanks for your help.
You should rewrite the query using join like:
$query = "SELECT *
FROM business_contacts bc
INNER JOIN internships i ON bc.id_business = i.id_supervisor_internship
WHERE internships.name_enterprise_internship = '$name_enterprise'";
If you need both ids then left join twice using both ids:
$query = "select
*
from internships i
left join business_contacts bc ON bc.id_business = i.id_supervisor_internship
left join business_contacts bc2 on bc2.id_business = i.id_promoter_internship
WHERE
i.name_enterprise_internship = '$name_enterprise'";
If you need only supervisor id:
$query = "select
*
from internships i
left join business_contacts bc ON bc.id_business = i.id_supervisor_internship
WHERE
i.name_enterprise_internship = '$name_enterprise'";
If you need only promoter id:
$query = "select
*
from internships i
left join business_contacts bc on bc.id_business = i.id_promoter_internship
WHERE
i.name_enterprise_internship = '$name_enterprise'";
To get use specific parameter in the join:
$query = "select
*
from internships i
left join business_contacts bc ON bc.id_business = i.id_promoter_internship and i.name_enterprise_internship = '$name_enterprise'";

How do I nest joins inside a from statement in Codeigniter

Okay, I've been tasked with rewriting a small, old PHP app in Codeigniter, and I ran into a bit a road bump. I'm not sure how to go about handling the joins in the query.
FROM(
(
(
(
(mobiledoc.labdata labdata JOIN mobiledoc.items items
ON (labdata.ItemId = items.itemID)
) JOIN mobiledoc.enc enc
ON (labdata.EncounterId = enc.encounterID)
) JOIN mobiledoc.users users_patient
ON (users_patient.uid = enc.patientID)
) JOIN mobiledoc.users users_Provider
ON (users_Provider.uid = enc.doctorID)
) JOIN mobiledoc.facilitygroupmembers facilitygroupmembers
ON (enc.facilityId = facilitygroupmembers.FacilityId)
)
And then after that FROM there are a few more joins, which I think would be fairly easy.
JOIN mobiledoc.facilitygroups facilitygroups ON (facilitygroups.Id = acilitygroupmembers.GroupId)
JOIN mobiledoc.patients patients ON (enc.patientID = patients.pid)
Any help would be greatly appreciated.
UPDATE:
I decided to just put the nested joins inside the for statement, and move on. Here's the original query.
$result = mysql_query("SELECT patients.ControlNO AS PatientID, users_patient.ulname AS patulname,
users_patient.ufname AS patufname, users_patient.uminitial AS patuminitial, users_patient.dob AS
patdob, users_Provider.ulname AS ULname, users_Provider.ufname AS UFname, items.itemName,
labdata.Notes,enc.date, enc.startTime FROM(((((mobiledoc.labdata labdata JOIN mobiledoc.items
items ON (labdata.ItemId = items.itemID)) JOIN mobiledoc.enc enc ON (labdata.EncounterId =
enc.encounterID)) JOIN mobiledoc.users users_patient ON (users_patient.uid = enc.patientID)) JOIN
mobiledoc.users users_Provider ON (users_Provider.uid = enc.doctorID)) JOIN
mobiledoc.facilitygroupmembers facilitygroupmembers ON (enc.facilityId =
facilitygroupmembers.FacilityId)) JOIN mobiledoc.facilitygroups facilitygroups ON
(facilitygroups.Id = facilitygroupmembers.GroupId) JOIN mobiledoc.patients patients ON
(enc.patientID = patients.pid) WHERE (facilitygroups.Name = '". $_POST['facility_id'] . "') AND
(items.itemName LIKE '%X RAY%' OR items.itemName LIKE '%Cast%' OR items.itemName LIKE '%Splint%'
OR items.itemName LIKE '%DEXA%') AND (enc.VisitType NOT IN ('', 'MT', 'TEL')) AND (enc.`date` =
'" . $_POST['txtYear'] . "-" . $_POST['txtMonth'] . "-" . $_POST['txtDay'] ."') ORDER BY
enc.startTime ASC") or die ("could not execute query!");
Here's the new query:
$this->db->select('patients.ControlNO as id');
$this->db->select('users_patient.ulname as lastName');
$this->db->select('users_patient.ufname as firstName');
$this->db->select('users_patient.uminitial as mInitial');
$this->db->select('users_patient.dob as dob');
$this->db->select('users_Provider.ulname as phys_lastName');
$this->db->select('items.itemName');
$this->db->select('labdata.notes');
$this->db->select('enc.date');
$this->db->select('enc.startTime');
$this->db->from('((((mobiledoc.labdata labdata JOIN mobiledoc.items items ON (labdata.ItemId
= items.itemID)) JOIN mobiledoc.enc enc ON (labdata.EncounterId = enc.encounterID)) JOIN
mobiledoc.users users_patient ON (users_patient.uid = enc.patientID)) JOIN mobiledoc.users
users_Provider ON (users_Provider.uid = enc.doctorID)) JOIN mobiledoc.facilitygroupmembers
facilitygroupmembers ON (enc.facilityId = facilitygroupmembers.FacilityId)) JOIN
mobiledoc.facilitygroups facilitygroups ON (facilitygroups.Id = facilitygroupmembers.GroupId)
JOIN mobiledoc.patients patients ON (enc.patientID = patients.pid)');
$this->db->where($where_array);
$this->db->like($like_array);
$this->db->or_like($or_like_array);
$this->db->where_not_in('enc.VisitType', $not_in);
$this->db->order_by('enc.startTime', 'asc');
$this->db->get();
And the output from that query:
SELECT `patients`.`ControlNO` as id, `users_patient`.`ulname` as lastName,
`users_patient`.`ufname` as firstName, `users_patient`.`uminitial` as mInitial,
`users_patient`.`dob` as dob, `users_Provider`.`ulname` as phys_lastName, `items`.`itemName`,
`labdata`.`notes`, `enc`.`date`, `enc`.`startTime` FROM ((((((mobiledoc.labdata labdata JOIN
mobiledoc.items items ON (labdata.ItemId = items.itemID)) JOIN mobiledoc.enc enc ON
(labdata.EncounterId = enc.encounterID)) JOIN mobiledoc.users users_patient ON (users_patient.uid
= enc.patientID)) JOIN mobiledoc.users users_Provider ON (users_Provider.uid = enc.doctorID))
JOIN mobiledoc.facilitygroupmembers facilitygroupmembers ON (enc.facilityId =
facilitygroupmembers.FacilityId)) JOIN mobiledoc.facilitygroups facilitygroups ON
(facilitygroups.Id = facilitygroupmembers.GroupId) JOIN mobiledoc.patients patients ON
(enc.patientID = patients.pid)) WHERE `facilitygroups`.`Name` = 0 AND `enc`.`date` = '12/05/2014'
AND `enc`.`VisitType` NOT IN ('', 'MT', 'TEL') AND `items`.`itemName` LIKE '%X RAY%' OR
`items`.`itemName` LIKE '%DEXA%' OR `0` LIKE '%items.itemName%' ORDER BY `enc`.`startTime` asc
With CI's active record you can easily join tables by using the following format
$qry = $this->db->select('*')
->from('table1')
->where('table1.id', 1)
->join('table2','table2.t_id = table1.id')
->get();
For more information take a look at CI's active record documentation
Also you can specify the join type by adding a third parameter to the join() function
$this->db->join('table3', 'table3.id = table2.t_id', 'left');

Zend DB select using Zend_Db_Expr

I've converted the following query in Zend framework way
SELECT
DISTINCT
eva.errata_number, eva.headline, err.owner,err.rootCause, err.description FROM
v_allevaluations eva, erratas err
WHERE
eva.errata_number=err.errata_number and stateCombined = 'Affected' &&
(Select releases_id in (SELECT release_id
FROM subscription WHERE user_id = 83) OR folder in (SELECT folder
FROM subscribed_ns WHERE user_id = 83))
Zend framework query:
$select = $db->select()
->distinct()
->from(array('eva'=>'v_allevaluations'),array('errata_number', 'headline'))
->join(array('err'=>'erratas'), 'eva.errata_number= err.errata_number',array('owner','rootCause','description'))
->where('stateCombined=?','Affected')
->where('select releases_id IN (?)', new Zend_Db_Expr("SELECT release_id FROM subscription WHERE user_id = ".$user_id.") OR folder in (SELECT folder
FROM subscribed_ns WHERE user_id = ".$user_id.")"));
When I print $select it prints
SELECT
DISTINCT
`eva`.`errata_number`, `eva`.`headline`, `err`.`owner`, `err`.`rootCause`, `err`.`description`
FROM
`v_allevaluations` AS `eva` INNER JOIN `erratas` AS `err` ON eva.errata_number= err.errata_number
WHERE
(stateCombined='Affected')
AND
(select releases_id IN (SELECT release_id FROM subscription WHERE user_id = 83) OR folder in (SELECT folder FROM subscribed_ns WHERE user_id = 83)))
It adds an extra bracket at the end after user_id = 83.
Could you please let me know what is wrong?
I assigned sub-queries to a variable and replaced it in the query
$select = $db->select()
->distinct()
->from(array('eva'=>'v_allevaluations'),array('errata_number', 'headline'))
->join(array('err'=>'erratas'), 'eva.errata_number= err.errata_number',array('owner','rootCause','description'))
->where('stateCombined=?','Affected')
->where('select releases_id IN (?)', new Zend_Db_Expr(" ".$get_subscribed_release_ids." ) OR folder in (".$get_subscribed_folders.""));
Sub queries:
$get_subscribed_release_ids = $db->select()
->from(array('subscription'), 'release_id')
->where('user_id =?',"$user_id");
$get_subscribed_folders = $db->select()
->from(array('subscribed_ns'), 'folder')
->where('user_id =?',"$user_id");

How to convert normal sql query to Zend_Db_Select?

Hi I want to convert my normal mysql query to zend.db.select;
I want to use this script:
$select = $db->select();
// Add a FROM clause
$select->from( ...specify table and columns... )
// Add a WHERE clause
$select->where( ...specify search criteria... )
// Add an ORDER BY clause
$select->order( ...specify sorting criteria... );
$select->limit(20, 10);
for my query below
SELECT
IF(derived_messages.toid = '$user', derived_messages.fromid,
derived_messages.toid) friend1,c.UserName,
derived_messages.message, derived_messages.fromid, derived_messages.toid,
derived_messages.is_read,derived_messages.type,derived_messages.id as mesid,
derived_messages.date,
(SELECT M.message_id FROM messagesmapped M where M.message_id= derived_messages.id AND M.user_id ='$user' AND M.important = 1) as MesMapid
FROM
(
SELECT *
FROM messages
WHERE messages.deleted_by NOT
IN ( $user )
ORDER BY Date DESC
) derived_messages
INNER JOIN Users c ON c.MemberID = IF(derived_messages.toid = '$user', derived_messages.fromid,
derived_messages.toid)
WHERE (derived_messages.id IN
(SELECT M.message_id FROM messagesmapped M where M.message_id= derived_messages.id AND M.user_id ='$user' AND M.important = 1)
AND
(derived_messages.toid='$user' OR derived_messages.fromid='$user'))
GROUP BY friend1 ASC
ORDER BY derived_messages.date DESC, derived_messages.id DESC LIMIT $limit $offset
I hope someone can help m on this.
Thank you.
It's possible but unlikely someone will write the query for you.
My recommendation on tackling such a query is to write each individual subquery as its own Zend_Db_Select object and then build the final query using the subqueries that you already have objects for.
Zend_Db_Select doesn't directly support the IF function, so for that you will need to use Zend_Db_Expr to add that statement into your select.
Here is a basic example of what I am talking about. Let's build the following query:
SELECT IF(msg.toId = 'drew010', msg.fromId, msg.toId), id, name, age, history.ip
FROM users
JOIN history ON users.id = history.userId
WHERE users.id = (
SELECT id FROM users WHERE loginCount > 1000
)
GROUP BY id,
ORDER BY age DESC
First build the subselect that select users where loginCount > 1000.
$subquery1 = $db->select()
->from('users', array('id'))
->where('loginCount > ?', 1000);
Next, build the outer query with the IF function:
$cols = array(
new Zend_Db_Expr('IF(' . $db->quoteInto('msg.toId = ?', 'drew010') . '), msg.fromId, msg.toId'),
'id', 'name', 'age'
);
$query = $db->select()
->from('users', $cols)
->join('history', 'users.id = history.userId', array('ip'))
->where('id = ?', $subquery1)
->group('id')
->order('age DESC');
echo $query;
The output:
SELECT
IF(msg.toId = 'drew010', msg.fromId, msg.toId),
`users`.`id`,
`users`.`name`,
`users`.`age`,
`history`.`ip`
FROM `users`
INNER JOIN `history`
ON users.id = history.userId
WHERE id = (
(SELECT `users`.`id`
FROM `users`
WHERE (loginCount > 1000))
)
GROUP BY `id`
ORDER BY `age` DESC
So the way to go is break the entire query into individual queries first, and then construct the outer query. Just have patience and take it slow. That and read over the Zend_Db_Select docs to get a full picture of what you have available to you.

Categories