How to use value from 'join' clause in 'where' clause? - php

There is join, and I need to include value from it in 'where'. Is there any way to do this? In other words, I want to apply 'where' clause only to that values, which being joined. I'm really got confused with it, and may be this task can be solved more easily.
$this->table = "CoolTable";
$sql = new Sql($this->getAdapter());
$select = $sql->select()
->columns(array(/*some expressions...*/))
->from($this->table)
->join(
array('ct' => 'CoolTable'),
new Expression('
ct.a = CoolTable.a AND
ct.b = CoolTable.b
'),
array()
)
/*another joins...*/
->where(array(
'CoolTable.a' => $someExternalVar,
'CoolTable.b = ?' => '$ct.a',
))
What about my tries:
'CoolTable.b = ?' => '$ct.a'
'CoolTable.b' => 'ct.a'
'CoolTable.b' => new Expression('ct.a') /*it's a really pity, yes*/
new Predicate\PredicateSet(
array(
new Operator(
'CoolTable.b',
Operator::OPERATOR_EQUAL_TO,
'ct.a'
),
),
Predicate\PredicateSet::TYPE_VALUE
),

Related

Zend Framework 2 "select where not in"

I have this simple query where I have a $posts Array that contains IDs of certain posts. And I am selecting the files associated with these posts basically:
->from(
['DO' => 'DOCUMENT']
)
->columns(
[
'POST_ID',
'FILENAME'
]
)
->where('DO.FILENAME LIKE "%'.$format.'%"')
->where(['DO.POST_ID' => $posts])
->order('DO.FILENAME DESC');
Now I want to select the files that are not related to these posts. So I need to do opposite of this:
->where(['DO.POST_ID' => $posts])
I cannot figure out how?
You need to use NOT IN operation
->from(
['DO' => 'DOCUMENT']
)
->columns(
[
'POST_ID',
'FILENAME'
]
)
->where('DO.FILENAME LIKE "%'.$format.'%"')
->where->addPredicate(new Zend\Db\Sql\Predicate\Expression('DO.POST_ID NOT IN (?)', array($posts)))
->order('DO.FILENAME DESC');
use Zend\Db\Sql\Predicate\NotIn;
$adapter = $this->tableGateway->getAdapter();
$sql = new Sql($adapter);
$select = $sql->select();
$select->from('produto');
$select->where->addPredicate->notIn('DO.POST_ID', [1,3,5]);
$select->order('status ASC');
$selectStr = $sql->getSqlStringForSqlObject($select);
echo $selectStr;
$results = $adapter->query($selectStr, $adapter::QUERY_MODE_EXECUTE);

CakePHP Retrieving data from multiple tables with select conditions

I am building an application using CakePHP and I am stuck on a problem retrieving data using a series of joins. In the simplified example below the join with the alias Delivery could have more than record and I want to bring back the record with a max value in a particular field in that table.
$inv_conditions = array( 'Invoice.invoice_date >=' => $DateFormatter->dateForDB($dateFrom),
'Invoice.invoice_date <=' => $DateFormatter->dateForDB($dateTo),
'Invoice.id >' => 385380 );
$join = array(array(
'table' => 'jobs',
'alias' => 'Jobs',
'type' => 'LEFT',
'conditions' => array('Invoice.job_id = Jobs.JOB_ID' )
),
array(
'table' => 'functional',
'alias' => 'Delivery',
'type' => 'LEFT'
'conditions'=> array('AND ' => array('Invoice.job_id = Delivery.JOB',
'Delivery.TYPE_STAGE = 1')
)
)
);
$invoices = $this->Invoice->find("all", array(
"fields" => array(
'Invoice.id',
'Invoice.job_id',
'Invoice.invoice_no',
'Invoice.consolidated_type',
'Invoice.customer_id_tbc',
'Invoice.invoice_date',
'Invoice.invoice_reference',
'Invoice.invoice_req',
'Jobs.PAYMENT_TYPE',
'Jobs.CUSTOMER',
'Jobs.MOST_RELEVANT_LINE',
'Delivery.DEPARTURE_DATE',
'Delivery.CNOR_CNEE_NAME',
'Delivery.TOWN_NAME',
),
"conditions" => $inv_conditions,
"joins" => $join
)
);
}
I can do this with SQL no problem as follows:
SELECT
jobs.JOB_ID,
jobs.CUSTOMER,
functional.JOB_LINE_ORDER,
functional.CNOR_CNEE_NAME,
functional.TOWN_NAME
FROM jobs JOIN functional ON
jobs.JOB_ID = 'M201409180267'
AND
functional.JOB = jobs.JOB_ID
AND
functional.TYPE_STAGE = 0
AND
functional.JOB_LINE_ORDER =
(SELECT MAX(JOB_LINE_ORDER) FROM functional
WHERE functional.JOB = 'M201409180267' AND functional.TYPE_STAGE = 0)
I have tried using the following to the conditions array:
'conditions' => array('AND ' =>
array( 'Invoice.job_id = Delivery.JOB',
'Delivery.TYPE_STAGE = 1'
'Delivery.JOB_LINE_ORDER = MAXIMUM(Delivery.JOB_LINE_ORDER)' )
)
This does bring back results but not the correct ones and the resulting SQL generated by Cake does have a select in the where clause. Is there a way of doing this when retrieving data in cake where the sql statement created will have a select in the where clause.
Any suggestions would be greatly appreciated.
Thanks
Bas
You need to use subquery to generate the select in the where clause. You can create a method in your model that does this and call it from your controller.
$subQuery = $db->buildStatement(
array(
'fields' => array(''),
'table' => $db->fullTableName($this),
'alias' => 'aliasName',
'limit' => null,
'offset' => null,
'joins' => array(),
'conditions' => $conditionsArray,
'order' => null,
'group' => null
),
$this
);
$subQuery = ' <<YOUR MAIN QUERY CONDITION (' . $subQuery . ') >>';
$subQueryExpression = $db->expression($subQuery);
$conditions[] = $subQueryExpression;
return $this->Model->find('list', compact('conditions'));

PHP. How to take data from 2 mysql tables instead of 1

Learning php and I am losing my mind trying to solve this for days now. Please help.
This is a code which goes thought a table COUPON, take data with a condition met, and download it afterwards. In this table COUPON I have USER_ID as number but I want to have a user name also, which is kept in another table USER.
How can I go to another table (USER) and take names (REALNAME) by this USER_ID which is the same in both tables?
if ( $_POST ) {
$team_id = abs(intval($_POST['team_id']));
$consume = $_POST['consume'];
if (!$team_id || !$consume) die('-ERR ERR_NO_DATA');
$condition = array(
'team_id' => $team_id,
'consume' => $consume,
);
$coupons = DB::LimitQuery('coupon', array(
'condition' => $condition,
));
if (!$coupons) die('-ERR ERR_NO_DATA');
$team = Table::Fetch('team', $team_id);
$name = 'coupon_'.date('Ymd');
$kn = array(
'id' => 'ID',
'secret' => 'Password',
'date' => 'Valid',
'consume' => 'Status',
);
$consume = array(
'Y' => 'Used',
'N' => 'Unused',
);
$ecoupons = array();
foreach( $coupons AS $one ) {
$one['id'] = "#{$one['id']}";
$one['consume'] = $consume[$one['consume']];
$one['date'] = date('Y-m-d', $one['expire_time']);
$ecoupons[] = $one;
}
down_xls($ecoupons, $kn, $name);
After this, I want to try to do the same thing using only SQL queries.
You would need to JOIN the tables in the SQL query
SELECT something FROM coupons as coupons JOIN user as user ON coupons.id=user.id
You should use join when you want to retrieve details from two tables.
Join table COUPON and table USER based on user_id . This should yield results you want.

how to use LIKE with conditions in sqlite or mysql with lithium recordset

so I can look for concrete values by doing
$recordset= Model::find('all', array(
'conditions' => array(
'condition' => $somevalue
)
))
however, what do I do if I want to match on a partial value?
right now, I've resorted to writing the query myself, a la:
$abc = Connections::get('default')->
read('SELECT * FROM myTable WHERE condition LIKE "%partial string%"');
Here's how I do an SQL 'like' search:
$user = User::find('all', array(
'conditions' => array(
'first_name' => array('like' => '%yeun%'))
)
);
'like' being the keyword, there.
That would generate a query like:
SELECT * FROM `users` AS `Users` WHERE (`first_name` like '%yeun%');
Hope that helps.

How to get all table columns without defining them in query?

I have two tables, User and Company. I have joining them like this:
$table = $this->getDbTable();
$select = $table->select();
$select->setIntegrityCheck( false );
$select->from( array('User'), array( 'id' => 'id',
'name' => 'User.name',
'gender' => 'User.gender',
'Company_id' => 'User.Company_id'
));
$select->join( 'Company', 'Company.id = User.Company_id',
array( 'Company_name' => 'Company.name' ,
'Company_address' => 'Company.address'
));
$rows = $table->fetchAll( $select );
It is working and giving me accurate result. Problem is that I have to mentions column names in above codes. I want to get all columns without mentioning them in above piece of code.
For example I want something like this that get all columns(But it is not providing all column values):
$table = $this->getDbTable();
$select = $table->select();
$select->setIntegrityCheck( false );
$select->from( array('User') );
$select->join( 'Company', 'Company.id = User.Company_id' );
$rows = $table->fetchAll( $select );
Thanks
Leaving away the second parameter to the from call should work: http://framework.zend.com/manual/en/zend.db.select.html#zend.db.select.building.columns

Categories