I've pure sql query like this:
SELECT concat(tyres, '-', engine, '-', body) as product, `date`, `type`, `note`
FROM `products` LEFT JOIN `shop`.`users` ON `user_id` = `shop`.`user`.`id`
and, I using Kohana query builder in following example
DB::select(array(DB::expr('concat(tyres, engine, body)'), 'product'))->from('products')->join('shop'.'users','LEFT')->on('user_id', '=', 'shop.users.id');
so, kohana's query not working. Please help
You can always use debugging to find out error.
You are join condition is wrong you need single string to enter database name and table name.
Replace join('shop'.'users','LEFT') with join ( 'shop.users', 'LEFT' )
$query = DB::select ( array (
DB::expr ( 'concat(tyres, engine, body)' ),
'product'
) )->from ( 'products' )->join ( 'shop.users', 'LEFT' )->on ( 'user_id', '=', 'shop.users.id' );
echo Debug::vars ( $query->compile () );
Here is out put:
string(125) "SELECT concat(tyres, engine, body) AS `product` FROM `products` LEFT JOIN `shop`.`users` ON (`user_id` = `shop`.`users`.`id`)"
Related
My emails_queue table contains more than 900k records so the query becomes slow to find a record that doesn't exist in that table.
I am using Codeigniter
Here's my query
$key = $this->config->item('encryption_key');
$query = $this->db
->select(
"
users.id, AES_DECRYPT(users.email, '$key') as email,
AES_DECRYPT(users.first_name, '$key') as first_name,
AES_DECRYPT(users.state, '$key') as state,
AES_DECRYPT(users.phone_number, '$key') as phone,
prescriptions.user_id, prescriptions.expire_date
"
)
->from('users')
->join('prescriptions', 'users.id = prescriptions.user_id', 'LEFT')
->where(
"AES_DECRYPT(users.email, '$key') NOT IN (SELECT to_email FROM emails_queue WHERE template = 'renewal_template')",
null,
false
)
->where(
"users.id NOT IN (SELECT user_id FROM prescriptions GROUP BY user_id HAVING count(user_id) > 1)",
null,
false
);
How can I make it execute faster?
NOT IN ( SELECT ... )
is often poorly optimized. Try to turn it into one of these:
WHERE NOT EXISTS ( SELECT 1 ... )
LEFT JOIN .. WHERE .. IS NULL
(To discuss further, please provide the generated SQL.)
My query below was working, I swear... now suddenly, it's dead, outputting 'ORA-00923 FROM keyword not found where expected'.. I cannot understand why... I have tried various linters and syntax checkers; I am simply iterating through array data and pushing to a oracle table/row - adding a new entry if table_id is not found, and updating table_id if it is found. What am I missing?
Data coming in is perfect too.. what am I doing incorrectly..
$fd = json_decode($df, true);
foreach ($fd as $key=>$data) {
var_dump($data);
$sql = "MERGE INTO app.table a
using (SELECT '${data[0]}' table_id,
'${data[1]}' fac_ident,
'${data[2]}' lg_name,
'${data[3]}' basic_tp,
'${data[4]}' catc_vd,
'${data[5]}' address,
'${data[6]}' assoc_city,
'${data[7]}' latitude,
'${data[8]}' longitude,
'${data[9]}' assoc_cnty,
'${data[10]}' assoc_st,
'${data[11]}' time_zone,
FROM dual) p
ON ( a.table_id = p.table_id )
WHEN matched THEN
UPDATE SET a.fac_ident = p.fac_ident,
a.lg_name = p.lg_name,
a.basic_tp = p.basic_tp,
a.catc_vd = p.catc_vd,
a.address = p.address,
a.assoc_city = p.assoc_city,
a.latitude = p.latitude,
a.longitude = p.longitude,
a.assoc_cnty = p.assoc_cnty,
a.assoc_st = p.assoc_st,
a.time_zone = p.time_zone,
WHEN NOT matched THEN
INSERT (table_id,
fac_ident,
lg_name,
basic_tp,
catc_vd,
address,
assoc_city,
latitude,
longitude,
assoc_cnty,
assoc_st,
time_zone)
VALUES (p.table_id,
p.fac_ident,
p.lg_name,
p.basic_tp,
p.catc_vd,
p.address,
p.assoc_city,
p.latitude,
p.longitude,
p.assoc_cnty,
p.assoc_st,
p.time_zone)";
..........
If your data contains a single quote then you are doing the equivalent of trying to perform an SQL injection attack.
Don't use variable parsing ${data[0]}; instead create your query using bind variables and pass in your data properly so you are not vulnerable to SQL injection attacks.
For example:
If you have the table:
CREATE TABLE table_name (
table_id VARCHAR2(100),
fac_ident VARCHAR2(100)
)
And you have a table_id of 1 and a fac_ident of 2 then your merge would be:
MERGE INTO table_name a
USING (
SELECT '1' table_id,
'2' fac_ident
FROM dual
) p
ON ( a.table_id = p.table_id )
WHEN matched THEN
UPDATE SET a.fac_ident = p.fac_ident
WHEN NOT matched THEN
INSERT (table_id, fac_ident )
VALUES (p.table_id, p.fac_ident );
This works.
However, if fac_ident has the value This value has a 'quote' inside it. then your query is:
MERGE INTO table_name a
USING (
SELECT '1' table_id,
'This value has a 'quote' inside it.' fac_ident
FROM dual
) p
ON ( a.table_id = p.table_id )
WHEN matched THEN
UPDATE SET a.fac_ident = p.fac_ident
WHEN NOT matched THEN
INSERT (table_id, fac_ident )
VALUES (p.table_id, p.fac_ident );
And fails with:
ORA-00923: FROM keyword not found where expected
More insidious, is if fac_indent has the value '||(SELECT secret_column FROM secret_data WHERE ROWNUM = 1)||' and then your query becomes:
MERGE INTO table_name a
USING (
SELECT '1' table_id,
''||(SELECT secret_column FROM secret_data WHERE ROWNUM = 1)||'' fac_ident
FROM dual
) p
ON ( a.table_id = p.table_id )
WHEN matched THEN
UPDATE SET a.fac_ident = p.fac_ident
WHEN NOT matched THEN
INSERT (table_id, fac_ident )
VALUES (p.table_id, p.fac_ident );
And, if the table SECRET_DATA exists and has the column SECRET_COLUMN then your query won't fail and users can start to do unexpected things with your query. Please don't let them do this and use best practice of formulating your queries using bind variables rather than string concatenation.
db<>fiddle here
I want to use union queries result in Not in in ZF2. Result of this query will return
Query: $selectLevelTwoPointFive->combine($selectLevelAll, 'UNION');
Result: ( SELECT `assigned`.`item_id` AS `item_id` FROM `assign_items_level_twopointfive` AS `assigned` ) UNION ( SELECT `assigned`.`item_id` AS `item_id` FROM `assign_items` AS `assigned` )
Now I want to use this query's result in 'not in' clause.
$select = $sql->select()->from(array(
"items" => "cu_items"
))->columns(array('item_name'=> new \Zend\Db\Sql\Expression(" group_concat(`items`.`item_name`)") ));
$select->join(array(
"ca" => "cu_areas"
), new Expression(" ca.area_id = items.area_id ")
, array(
'area_name'
), $selectLevelAll::JOIN_INNER);
$select->where->addPredicate(new \Zend\Db\Sql\Predicate\Expression('items.item_id NOT IN (?)',
array($selectLevelTwoPointFive)));
The result is:
SELECT group_concat(`items`.`item_name`) AS `item_name`, `ca`.`area_name` AS `area_name` FROM `cu_items` AS `items` INNER JOIN `cu_areas` AS `ca` ON ca.area_id = items.area_id WHERE `items`.`is_opted` = 'yes' AND `ca`.`is_opted` = 'yes' AND items.item_id NOT IN ((( SELECT `assigned`.`item_id` AS `item_id` FROM `assign_items_level_twopointfive` AS `assigned` ) UNION ( SELECT `assigned`.`item_id` AS `item_id` FROM `assign_items` AS `assigned` )))
It is showing mysql error :
Error Code: 1064. You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'UNION ( SELECTassigned.item_idASitem_idFROMassign_itemsASassigne' at line 1`
My required query is:
SELECT group_concat(items.item_name) AS item_name, ca.area_name AS area_name FROM cu_items
AS items INNER JOIN cu_areas AS ca ON ca.area_id = items.area_id
WHERE items.is_opted = 'yes' AND ca.is_opted = 'yes' AND items.item_id NOT IN
(
(
SELECT assigned.item_id AS item_id FROM assign_items_level_twopointfive AS assigned
UNION ( SELECT assigned.item_id AS item_id FROM assign_items AS assigned )
)
)
Actually when i use combine() it adds round bracket (first query) union (second query) But in not I need first query union second query.
Please help. If any one suggest the mysql changes it also fine.
Thanks God, Find the page.
We need to override the setSpecification()
Here is the link for the answer.
we can override the query output
I have the following query:
select
`t`.`id` AS `id`,
`rm`.`role_id` AS `role_id`,
`t`.`id` AS `sequence`,
`t`.`parent_id` AS `parent_id`,
`t`.`label` AS `label`,
`t`.`order` AS `order`,
(case
when isnull(`rm`.`id`) then 0
else 1
end) AS `description`,
`tb`.`label` AS `parent_label`
from
((`tbl_menu` `t`
left join `tbl_menu` `tb` ON ((`t`.`parent_id` = `tb`.`id`)))
left join `tbl_role_menu` `rm` ON ((`rm`.`menu_id` = `t`.`id`))) and rm.role_id = $role_id
where
isnull(`tb`.`label`)
union select
`t`.`id` AS `id`,
`rm`.`role_id` AS `role_id`,
`t`.`parent_id` AS `parent_id`,
`t`.`parent_id` AS `sequence`,
`t`.`label` AS `label`,
`t`.`order` AS `order`,
(case
when isnull(`rm`.`id`) then 0
else 1
end) AS `description`,
`tb`.`label` AS `parent_label`
from
((`tbl_menu` `t`
left join `tbl_menu` `tb` ON ((`t`.`parent_id` = `tb`.`id`)))
left join `tbl_role_menu` `rm` ON ((`rm`.`menu_id` = `t`.`id`))) and rm.role_id = $role_id
where
(`tb`.`label` is not null)
order by `sequence` , `parent_id` , `label`
On both queries, on the second left join I have to pass a variable $role_id. Currently, I have this query on a view but if a try passing a criteria condition, the resulting query is
select * form menu_links where role_id = $role_id
Being menu_links the name of the view. This doesn't give me the result I want. I need a way to add this parameter to this query and transform it into a CDbCriteria in order to pass it to a CGridView. Any help?
Thanks.
Consider using CArrayDataProvider.
CArrayDataProvider acts as a wrapper around a simple associative array and CGridView won't know the difference. You can even apply pagination, sorting etc. An example showcasing these features can be found in the documentation:
$rawData=Yii::app()->db->createCommand('SELECT * FROM tbl_user')->queryAll();
$dataProvider=new CArrayDataProvider($rawData, array(
'id'=>'user',
'sort'=>array(
'attributes'=>array(
'id', 'username', 'email',
),
),
'pagination'=>array(
'pageSize'=>10,
),
));
I give you a simple example you will figure out how to apply it to you case
$sql= "select * form menu_links where role_id = :role_id";
$role_id='Something you will get from your could';
$command = Yii::app()->db->createCommand($sql);
// And finally the command you can replace the role id with varibale is
$command->bindParam(":role_id", $role_id, PDO::PARAM_STR);
$result = $command->queryAll();
I hope this was what you were asking.
Using Zend DB. I am trying to figure out how to write this query using the DB Class.
select
org.orgid
org.role
user.userid
user.firstname
from orgTable org
join userTable user on org.userid = user.userid
where org.orgid = 'generated-id'
from the documents I understand or think I understand how to do it with one definition using an AS like condition, but even then Im still not sure. Eventually this will branch out into a multi table join, based on cross table conditions so not sure how to achieve this to begin with.
I think this is what are you looking for
$db = Zend_Db::factory( ...options... );
$select = $db->select()
->from(array('org' => 'orgTable'),
array(
'orgid' => 'org.orgid',
'role' =>'org.role',
'userid' =>'user.userid',
'firstname' =>'user.firstname'
))
->join(array('user' => 'userTable'),
'org.userid = user.userid',array())
->where('org.orgid = ?',$generated_id);
Here is a Zend_Db_Select that returns the result you are looking for.
$select = $db->select()
->from(array('org' => 'orgTable'), array('orgid', 'role'))
->join(array('user' => 'userTable'), 'org.userid = user.userid', array('userid', 'firstname'))
->where('org.orgid = ?', 'generated-id');
You can use the array notation for table names to get the aliased names in the query.
Hope that helps.
In zend framework 2 , the following code helps you what are you looking for
$generated_id = 1 ;
$select = new \Zend\Db\Sql\Select( array('org' =>'orgTable'));
$select->columns(array('orgid','role') )
->join( array('user' => 'userTable'),
'org.userid = user.userid',
array('userid','firstname')
)->where( array('org.orgid' => $generated_id ) );
if your adapter platform is mysql, then for printing sql
$mysqlPlatform = new \Zend\Db\Adapter\Platform\Mysql();
echo $select->getSqlString( $mysqlPlatform );
which print sql as
SELECT
`org`.`orgid` AS `orgid`,
`org`.`role` AS `role`,
`user`.`userid` AS `userid`,
`user`.`firstname` AS `firstname`
FROM
`orgTable` AS `org`
INNER JOIN `userTable` AS `user`
ON `org`.`userid` = `user`.`userid`
WHERE
`org`.`orgid` = '1'