Firstly I explain my issue :
I have two tables Job and JobCategory :
job:
-------------------------------------------------
| id | category_job_id | job_name | keywords |
-------------------------------------------------
JobCategory:
-------------------------
| id | categoty_name |
-------------------------
tho two tables is related by foreign key "category_job_id".
In this application I'm using Propel ORM. I hoped to make search using three fields keywords, job_name and category_name.
The first field is keywords is "input" who I can write keywords, the second field is Category_name is a "select", list of category. The third field is Job_name and is a "select", list of Job name, and if is not empty the keywords fields will be ignored.
I make function of search like this, but it doesn't work for me:
public function searchFilter($job,$category,$keyword)
{
$order = isset($this->order) ? $this->order : Criteria::ASC;
$job = '%' .$job. '%';
$category = '%' .$category. '%';
$c = new Criteria();
$c->addJoin(JobPeer::CATEGORY_JOB_ID, JobCategoryPeer::ID);
if((null !== $category) AND ($category !== ""))
{
$c->addOr(JobCategoryPeer::CATEGORY_NAME,$category, Criteria::LIKE);
}
if((null !== $job) AND ($job !== ""))
{
$c->addOr(JobPeer::JOB_NAME,$job, Criteria::LIKE);
}
$query = JobQuery::create(null, $c)
->joinWith('Job.JobCategory')
->orderByDateOfJob($order);
if((null !== $keyword) AND ($keyword !== "")){
$keyword = '%' .$keyword. '%';
$query->filterByKeywords($keyword, Criteria::LIKE);
}
$results = $query->find();
return $results;
}
But the search is all cases is wrong!
I think something like this will work. If not, you can get the generated SQL before issuing the find() (see below) so that you (and we) can see what the output might be.
public function searchFilter($job,$category,$keyword)
{
$order = isset($this->order) ? $this->order : Criteria::ASC;
$query = JobQuery::create()->joinWith('JobCategory');
$conditions = array();
if((null !== $category) AND ($category !== ""))
{
$query->condition('catName', "JobCategory.CategoryName LIKE ?", "%$category%");
$conditions[] = 'catName';
}
if((null !== $job) AND ($job !== ""))
{
$query->condition('jobName', "Job.JobName LIKE ?", "%$job%");
$conditions[] = 'jobName';
}
if (sizeOf($conditions) > 1)
{
// join your conditions with an "or" if there are multiple
$query->combine($conditions, Criteria::LOGICAL_OR, 'allConditions');
// redefine this so we have the combined conditions
$conditions = array('allConditions');
}
// add all conditions to query (might only be 1)
$query->where($conditions);
if((null !== $keyword) AND ($keyword !== ""))
{
$query->filterByKeywords("%$keyword%", Criteria::LIKE);
}
$query->orderByDateOfJob($order);
$sql = $query->toString(); // log this value so we can see the SQL if there is a problem
return $query->find();
}
Related
i am unable to fit my query into zf2 query, i can fit simple join query but i can not write for more complex sub queries.
please help me to do this.
SELECT `created_date` FROM `salesmodule_discussed_topic` dt WHERE dt.`meeting_id` IN(
SELECT ma.`meeting_id` FROM `salesmodule_meeting_agent` ma WHERE ma.`agent_id`=30547
)
public function getLastmeetingdate() {
$select = new Select();
$select->from(array('dt' => 'salesmodule_discussed_topic'));
$select->columns(array('created_date'));
$select->where(array('ma.`agent_id` => 30547));
$resultSet = $this->tableGateway->selectWith($select);
return $resultSet->buffer();
}
The previous example is bad because has an sql injections. You need make a subquery using Select.
public function getLastmeetingdate() {
$subQuery = new Select();
$subQuery->from(array('ma' => 'salesmodule_meeting_agent'));
$subQuery->columns(array('meeting_id'));
$subQuery->where(array('ma.agent_id' => 30547));
$select = new Select();
$select->from(array('dt' => 'salesmodule_discussed_topic'));
$select->columns(array('created_date'));
$select->where->in('dt.meeting_id', $subQuery);
return $this->tableGateway->selectWith($select);
}
public function fetchAllSubQuery($id = '') {
$columns = array("*");
$where = "main_booking_id IN (SELECT
b1.`main_booking_id`
FROM
`booking_sector` b1
WHERE b1.`connected_booking_id` = '$id' OR b1.`main_booking_id` = '$id') ";
$resultSet = $this->tableGateway->select(function (Select $select) use ($where,$columns) {
$select->where($where);
$select->columns($columns);
});
$resultSet->buffer();
// $resultSet->next();
return $resultSet;
}
I'm new to ZF2.
How can I write a query like this?
SELECT * FROM users WHERE id = 1 AND status != 2
My code Model:
public function getUser($where = array())
{
$select = $this->sql->select();
$select->from(self::TABLE);
$select->where($where);
$select->order('name ASC');
return $statement->execute();
}
I am using: Zend\Db\Sql
Thanks.
Look at the docs here.
So $where can be a string or Closure, too.
Call it in your case like:
$user = $object->getUser('status != 2');
Oh, I missed the first condition:
$user = $object->getUser(array('id = 1', 'status != 2'));
EDIT:
You can for sure leave the = array() default value. I don't know why but I confused it with type hinting. (array $where)
public function getUser( where = array() ) {
$select = $this->sql->select();
$select->from(self::TABLE);
$select
->where->nest()
->equalTo( 'id' => where['id'] )
->or
->notEqualTo( 'status' => where['status'] )
->unnest();
$select->order('name ASC');
return $statement->execute();
}
use like this:
getUser( array(
'id' => 1,
'where' => 2,
) );
I have some query like below
var email= (from c in dataContext.tblC
where (c.AA == aa)
select c.email).ToList();
string emails = email.Aggregate((a, b) => a + "," + b);
Now I need another column SecEmail, I can't just (...select c.email, c.SecEmail).ToList().
Any suggestion for I can get list like (email1, SecEmail1, email2, email3, SecEmail3, email4...)
if you're working with dynamic objects:
var email = (from c in dataContext.tblC
where c.AA == aa
select new {
email = x.email,
secemail = c.secEmail,
// ...
}).ToList(); // IList<dynamic> & IDE will know what properties
// you supplied in the `select new { }`
Otherwise build a model and populate it:
public class SelectModel
{
public String email { get; set; }
public String secemail { get; set; }
}
var email = (from c in dataContext.tblC
where c.AA == aa
select new SelectModel {
email = x.email,
secemail = c.secEmail,
// ...
}).ToList(); // IList<SelectModel>
If you want the returned rows turned in to an email to header:
var email = String.Join(", ", (
from c in dataContext.tblC
where c.AA == aa
select c.email
).AsEnumerable());
Which would make:
+------------------+
| email |
|------------------|
| foo#contoso.com |
| bar#contoso.com |
| baz#contoso.com |
+------------------+
Turn in to:
foo#contoso.com, bar#contoso.com, baz#contoso.com
Multi-column concat:
var email = (from c in dataContext.tblC
where c.AA == AA
select new { email = c.email, secEmail = c.secEmail }).AsEnumerable();
var to = String.Join(", ",
email.Select(x => x.email)
.Concat(email.Select(y => y.secEmail))
// .Concat(eail.Select(y => x.thirdColumn))
// ...
);
I feel like I must me missing something very simple. It's a very simple task, all I want to do is get something like:
SELECT * FROM lookup_items
JOIN lookup ON lookup_items.lookup_id = lookup.id
This returns all the columns for all the joined tables, in regular SQL. Here's my attempt in zf2:
$select = new Select();
$select->from('lookup_items');
$select->join('lookup', 'lookup_items.lookup_id = lookup.id');
The result set only includes the columns in 'lookup_items'. I've tried various ways to get the 'lookup' columns, including:
$select->columns(array('lookup_items.*', 'lookup.*'));
But they all just blow up. Surely there's a way to do this, and it's just so simple I'm missing it completely.
I thought a simple example would be avoid confusion, but here's more code:
class LookupItemsTable extends AbstractTableGateway
{
public function getList($resource)
{
$system_name = str_replace('*', '%', strtoupper($resource));
$joinTable = 'lookup';
$select = new Select();
$select->from($this->table);
$select->join($joinTable, "{$this->table}.lookup_id = {$joinTable}.id");
$where = array();
$where[] = "{$this->table}.enabled is true";
$where[] = "{$joinTable}.enabled is true";
$where[] = "UPPER({$joinTable}.system_name) ilike '{$system_name}'";
$select->where($where);
$sort[] = 'sort_order ASC';
$sort[] = 'value ASC';
$select->order($sort);
$rowset = $this->selectWith($select);
return $rowset;
}
}
Where:
$resource = $this->params()->fromRoute('resource', 'BUSINESS');
And $this->table is 'lookup_items'. Really all I want to do is get columns from both joined tables. I guess there's a zf2 way to just make a straight SQL statement without all the OO falderal, so I could just force it that way. But I'd rather work within the framework as much as possible.
Just change this line
$select->join('lookup', 'lookup_items.lookup_id = lookup.id');
to
$select->join('lookup', 'lookup_items.lookup_id = lookup.id', array('lookupcol1', 'lookupcol2');
Raj answer is the best one but it only works if you don't forget to add these fiels in your LookupItems model.
class LookupItems
{
// Your lookup_items fields here...
...
// And the added lookup fields here, the ones you add in the array
public $lookupcol1;
public $lookupcol2;
And in the exchangeArray method :
public function exchangeArray($data)
{
// .... your fields, and the new ones
$this->lookupcol1 = (! empty($data['lookupcol1'])) ? $data['lookupcol1'] : null;
$this->lookupcol2 = (! empty($data['lookupcol2'])) ? $data['lookupcol2'] : null;
}
I figured it out.
Added this:
$select->columns(array('*'));
And then this near the end:
$sql = new Sql($this->adapter);
$statement = $sql->prepareStatementForSqlObject($select);
$rowset = $statement->execute();
This returns the expected result, with the caveat that now my rows are returned as associative arrays instead of objects.
This is how you can create queries with join in zf2.
$resultSet = $this->select(function (Select $select) {
// omit the table name
//$select->from('foo');
$select->join('users', "users.id foo.createdby", 'firstname', '');
$select->order('id ASC');
// echo $select->getSqlString();// to print your query
});
$entities = array();
foreach ($resultSet as $row) {
$entity = new Entity\Foo();
$entity->setId($row->id)
->setFullname($row->fullname)
->setCaseid($row->caseid)
->setTestimonial($row->testimonial)
->setSortorder($row->sortorder)
->setActive($row->active)
->setCreated($row->created)
->setModified($row->modified)
->setFirstname($row->firstname)
->setCreatedby($row->createdby);
$entities[] = $entity;
}
return $entities;
I want to write if condition inside where clause. because if first name or last name is null I don't wani to add it in where clause . other wise I want to add it.
so I write
var query1 = from opv in _opvRepository.Table
join o in _orderRepository.Table on opv.OrderId equals o.Id
join gr in _graduandRepository.Table on opv.graduand_id equals gr.graduand_id
join pv in _productVariantRepository.Table on opv.ProductVariantId equals pv.Id
join p in _productRepository.Table on pv.ProductId equals p.Id
where (opv.ceremony_id == ceremony_id) &&
(!o.Deleted) && (opv.IsHireItem == true) &&
(!p.Deleted) &&
(!pv.Deleted) && (opv.ceremony_id == ceremony_id)
// group opv by opv.OrderId into g
select new
{
opvTable = opv,
grTable = gr,
};
// This is not working. I have problem in here. How to add this??
if (!String.IsNullOrEmpty(Fname))
query1 = query1.Where(grTable = > grTable.first_name == Fname);
var result = query1.ToList().Select(x =>
{
return new HireItemReportLine()
{
OrderId = x.opvTable.OrderId,
OrderDate=x.opvTable.Order.CreatedOnUtc,
Amount= x.opvTable.Order.OrderSubtotalExclTax,
PaymentMethod = x.opvTable.Order.PaymentMethodSystemName,
paidDate = x.opvTable.Order.CreatedOnUtc,
Fname = x.grTable.first_name,
MName = x.grTable.middle_name,
LName = x.grTable.last_name,
};
}).ToList();
What is the wrong with my cording??
Note that your original query selects an anonymous type with two properties: opvTable and grTable. So, you need to use one of those properties in the subsequent Where clause, like this:
query1 = query1.Where(item => item.grTable.first_name == Fname);