my table
This is my table i have to display the data using multiple where conditions. First i select using dms_expire_date,for this i got answer and i am using dms_doc_name in where conditions but i didn't got correct result.
I have tired so far.
]
See this picture if i use "or" in "where" i got testie not within this date.but if i use "and" in "where" i didn't got result for dms_expiry_date
See this picture
i don't know how to do this.please help to solve this problem.
SELECT * FROM `dms_document` WHERE dms_expire_date BETWEEN '2020-05-01' AND '2020-07-16' AND dms_doc_name = '' OR dms_category_id = '' OR dms_subcategory_id=''
I have tired in array also but i didn't result.
$this->db->select('*');
$this->db->join('dms_category as C', 'C.dms_category_id = D.dms_category_id', 'left outer');
$this->db->join('dms_sub_category as S', 'S.dms_subcategory_id = D.dms_subcategory_id', 'left outer');
$this->db->where('dms_expire_date >=', $newstart);
$this->db->where('dms_expire_date <=', $newend);
$this->db->where(array('dms_doc_name' =>$docname,'D.dms_category_id'=>$category,'D.dms_subcategory_id'=>$subcategory));
$data['documents']= $this->db->get('dms_document as D')->result_array();
try
SELECT *
FROM dms_document
WHERE dms_expire_date BETWEEN $newstart AND $newend
AND CASE WHEN $docname IS NULL THEN 1 = 1 ELSE dms_doc_name = $docname END
AND CASE WHEN $category IS NULL THEN 1 = 1 ELSE dms_category_id = $category END
AND CASE WHEN $subcategory IS NULL THEN 1 = 1 ELSE dms_subcategory_id = $subcategory END
--
edited. waiting for clearance.
if I get what you mean correctly, it is problem with understanding AND, OR, and the priority with brackets ()
--
if anyone want to use the fiddle, I have created the sample data for this issue
You can write OR using CodeIgniter's or_where() (v3 docs) or orWhere() (v4 docs).
//your initial query
$sql = "SELECT
*
FROM
`dms_document`
WHERE
dms_expire_date BETWEEN '2020-05-01' AND '2020-07-16'
AND dms_doc_name = ''
OR dms_category_id = ''
OR dms_subcategory_id=''";
//building the same query using CI
$this->db->select('*');
$this->db->from('dms_document');
$this->db->where('dms_expire_date >=', '2020-05-01');
$this->db->where('dms_expire_date <=', '2020-07-16');
$this->db->where('dms_doc_name', '');
$this->db->or_where('dms_category_id', '');
$this->db->or_where('dms_subcategory_id', '');
You can confirm the query this generates by running $this->db->_compile_select(); or $this->db->last_query(); (https://stackoverflow.com/a/6145021/1499877 for reference).
echo '<pre>';
var_dump($sql);
var_dump($this->db->_compile_select());
echo '</pre>';
die();
Related
I want to do a subtraction operator between entotalitem and extotalitem.query that I use retrieve data from the same table that is tbl_orders_data.
I have tried by creating 2 queries, the first is the query to retrieve entotalitem and the second query to retrieve extotalitem
$encheck = DB::table('tbl_orders_data')
->select('slot_id', DB::raw('sum(total_item) as entotalitem'))
->where('id_order_data', 'like', 'PBM' . '%')
->groupBy('slot_id')
->pluck('entotalitem');
$excheck = DB::table('tbl_orders_data')
->select('slot_id', DB::raw('sum(total_item) as extotalitem'))
->where('id_order_data', 'like', 'PBK' . '%')
->groupBy('slot_id')
->pluck('extotalitem');
$en = $encheck;
$ex = $excheck;
dd($en - $ex);
Should I only need to use one query? or should I make 2 queries as I have tried?
please help me, thanks
You may use conditional aggregation here:
$check = DB::table('tbl_orders_data')
->select('slot_id', DB::raw("sum(case when id_order_data like 'PBM%' then total_item else 0 end) -
sum(case when id_order_data like 'PBK%' then total_item else 0 end) as totalitem"))
->groupBy('slot_id')
->pluck('totalitem');
I need to write this query with Doctrine. How can I write it down using QueryBuilder?
SELECT charges.id, charges.currency, charges.total_transactions,
charges.total_volume, charges.commission, refunds.total_payouts
FROM
(SELECT ...very long query...) charges
LEFT JOIN
(SELECT ...very long query...) refunds
ON charges.id = refunds.id AND charges.currency = refunds.currency
You can use Native SQL and map results to entities:
use Doctrine\ORM\Query\ResultSetMapping;
$rsm = new ResultSetMapping;
$rsm->addEntityResult('AppBundle:Charges', 'charges')
->addEntityResult('AppBundle:Refunds', 'refunds')
->addFieldResult('charges', 'id', 'id')
->addFieldResult('charges', 'currency', 'currency')
->addFieldResult('charges', 'total_transactions', 'total_transactions')
->addFieldResult('charges', 'total_volume', 'total_volume')
->addFieldResult('charges', 'commission', 'commission')
->addFieldResult('refunds', 'total_payouts', 'total_payouts')
;
$sql = "
SELECT
charges.id,
charges.currency,
charges.total_transactions,
charges.total_volume,
charges.commission,
refunds.total_payouts
FROM
(SELECT ...very long query...) charges
LEFT JOIN
(SELECT ...very long query...) refunds ON charges.id = refunds.id AND charges.currency = refunds.currency
WHERE some_field = ?
";
$query = $this->getEntityManager()->createNativeQuery($sql, $rsm);
$query->setParameter(1, $name);
$entities = $query->getResult();
You can use DQL like this:
$dql = "SELECT ...";
$q = $entityManager->createQuery($dql)->setParameters($arrayParameters);
$result = $q->execute();
or QueryBuilder for each sub-query, like:
// subquery 1
$subQuery1 = $entityManager->createQueryBuilder()
->select('...')
->from('...')
->getDQL()
;
// subquery 2
$subQuery2 = ...
// etc
// ...
// main query
$query = $entityManager->createQueryBuilder()
->select('...')
->from('...', $subQuery1)
->leftJoin('...', $subQuery1->getDQL()),
->where()
;
PS: I just try provide gist for you... hope now you have clue...
Now I found out that it's impossible.
Comment created by stof:
DQL is about querying objects. Supporting subselects in the FROM clause means that the DQL parser is not able to build the result set mapping anymore (as the fields returned by the subquery may not match the object anymore).
This is why it cannot be supported (supporting it only for the case you run the query without the hydration is a no-go IMO as it would mean that the query parsing needs to be dependant of the execution mode).
In your case, the best solution is probably to run a SQL query instead (as you are getting a scalar, you don't need the ORM hydration anyway)
Source: https://github.com/doctrine/doctrine2/issues/3542
The code is in EventUserTypes model
$this->find()
->select(['event_usertypes.user_type_id' , 'usertypes.name'])
->leftJoin('usertypes' , 'event_usertypes.user_type_id = usertypes.id')
->where(['event_usertypes.event_id'=>$event_id])
->all()
There is no error exept that it is only returning the columns of first table
and not the joined table. Its been 2 hours and have waisted too much energy on what is going wrong ? Any idea ?
If I select * then it returns all columns of first table
and if do this
select(['event_usertypes.user_type_id' , 'usertypes.name'])
it only returns event_usertypes.user_type_id not the name from the joined table
Please help me out
Try doing a direct DB query, to ensure that the usertypes table will be available in your query results:
$query = new \yii\db\Query;
$query->select(['e.user_type_id', 'u.name'])
->from('event_usertypes e')
->leftJoin('usertypes u', 'e.user_type_id = u.id')
->where(['e.event_id'=> $event_id]);
$command = $query->createCommand();
$resp = $command->queryAll();
Have a look at this SO question which was similar to yours. Also here is a link to the Yii documentation, in case this might help.
Please try like this
$query = new \yii\db\Query;
$query->select(['event_usertypes.user_type_id' , 'usertypes.name'])
->from('event_usertypes')
->leftJoin('usertypes' , 'event_usertypes.user_type_id = usertypes.id')
->where(['event_id'=> $event_id])->all();
$query->createCommand();
I was told that I could check whether a SELECT statement finds a column with the syntax
$rows = query( "SELECT * FROM tbl WHERE id = idx");
if ( $rows == false )
and it seems to work.
Anyway, if I check if ( $rows == 0 ) it doesn't return the same value.
Shouldn't 0 and false be the same (apart from the type, of course)?
What's the actual value returned by the query when it finds no row? I ask because it doesn't seems to be false, since the statement var_dump( $rows === false ) prints false..
***EDIT: I'm sorry guys, query() was a function from a library someone else wrote and I had no idea (i'm starting now with sql...). It simply excutes an SQL statement, returning an array of all rows in result set or false on (non-fatal) error (like row not found).
I have still a little question, though.
The function returns false when it finds no row, so shouldn't I be able to catch that with if ( $rows === false )?
Why var_dump(false) doens't print me out anything, while var_dump(true) prints me out 1?
I'm not pretty sure if you use simple mysql_* functions, MySQLi or PDO but in any case $rows is not returning the number of resulting rows. It is a boolean value / object returned / created depending of success of your query.
$sql = $mysqli->query("SELECT * FROM tbl WHERE id='1'");
if(!$sql->error)
$number_of_rows = $sql->num_rows; // for sure it will output 1
Trying to do this in Doctrine2:
...->createQuery('SELECT m.id, (m.status != 1) as verified...
But that throws an error - if I take parenthesis off I get another error. How do I achieve this m.status comparison?
Thanks
Doctrine 2 doesn't support these comparisons in the SELECT clause (at least not up to 2.3, not sure about 2.4).
You can use a CASE expression as workaround:
SELECT m.id, CASE WHEN m.status != 1 THEN 1 ELSE 0 END AS verified ...
or:
SELECT m.id, CASE WHEN m.status = 1 THEN 0 ELSE 1 END AS verified ...
If you need verified for an ORDER BY clause (or something like that), but don't actually need it in the result, you can use the HIDDEN expression:
SELECT m.id, CASE WHEN m.status = 1 THEN 0 ELSE 1 END AS HIDDEN verified ...
A completely different solution is to write a custom DQL function.
You can use the solution proposed here: Cumulative DQL with Doctrine
When working with entities, keep in mind that adding selects will make the query return an array for each result:
$res = $em->createQueryBuilder()
->from('BlogPost', 'p')
->select('p')
->addSelect('(2+3) AS dummy')
->getQuery()->getResult();
Iterating over $res will return an array:
foreach($res as $mixed){
echo get_class($mixed[0]); //$mixed[0] contains the BlogPost
echo $mixed['dummy']; //displays the dummy result (5)
}
check this out: 13.2.4. Using Expr* classes to create conditionals
using Expression methods you could do something like:
$qb = $this->entityManager->createQueryBuilder();
$query = $qb->select('m.id')
->from('Entities\MyEntity', 'm')
/*neq() is the "not equal" comparison function*/
->where($qb->expr()->neq('m.status', $someValue)),
->getQuery();