Zend DB select using Zend_Db_Expr - php

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");

Related

Join table using two columns of the tables

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

Zend Framework 2 Union Select with order

I have this Sql code:
( SELECT `column1` FROM `table_1` WHERE `column2` > 2 )
UNION
( SELECT `column1` FROM `table_2` WHERE `column2` < 10 )
ORDER BY `column1` ASC;
How to do that with Zend Framework 2?
Zend Framework 2 Zend\Db\Sql does not provide a Union method yet you'll have to either write it yourself or use a JOIN.
$sql = new Sql($this->adapter);
$select = $sql->select();
$select->from($this->table)
->join('table_1', 'table_2.column1 = table_1.column1');
$where = new Where();
$where->greaterThan('column2', 2) ; //youll have to add a and here with a lessThan
$select->where($where);
$statement = $sql->prepareStatementForSqlObject($select);
$result = $statement->execute();
Honestly speaking I did not try this example, but it should atleast give you a Idea.

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.

Fetch index information in PostgreSQL 8.4

I need to fetch the following information about indices on a specific table:
index name
columns that are indexed
unique or not?
How can I do that in PostgreSQL 8.4?
NOTE: I have to be able to call this stuff with PHP. Just saying...
EDIT: I first had this query, but it only works starting with PostgreSQL 9.0:
SELECT t.relname AS table_name,
relname AS index_name,
a.attname AS column_name,
ix.indisunique
FROM pg_class t,
pg_class i,
pg_index ix,
pg_attribute a,
pg_constraint c
WHERE t.oid = ix.indrelid
AND i.oid = ix.indexrelid
AND a.attrelid = t.oid
AND i.oid = c.conindid
AND a.attnum = ANY(ix.indkey)
AND c.contype != 'p'
AND t.relkind = 'r'
AND t.relname = 'tablename'
ORDER BY t.relname, i.relname
You could simply use pg_indexes which will include the full CREATE TABLE statement (and therefor the information about the columns and the uniqueness).
Alternatively, the following should work:
select t.relname as table_name,
ix.relname as index_name,
array_to_string(array_agg(col.attname), ',') as index_columns,
i.indisunique
from pg_index i
join pg_class ix on ix.oid = i.indexrelid
join pg_class t on t.oid = i.indrelid
join (select ic.indexrelid,
unnest(ic.indkey) as colnum
from pg_index ic) icols on icols.indexrelid = i.indexrelid
join pg_attribute col on col.attrelid = t.oid and col.attnum = icols.colnum
where t.relname = 'tablename'
group by t.relname, ix.relname, i.indisunique
order by t.relname,
ix.relname
It doesn't return the columns in the correct order though. But I didn't have time to dig deeper into that.

Zend_Db_Select: Working with JOIN's

I have this query:
SELECT
groups.name
categories.name,
categories.label
FROM
groups
JOIN
categories
ON
(categories.group1 = groups.id
OR
categories.group2 = groups.id)
AND
groups.label = :section
AND
categories.active = 1
Now, this is my JOIN using Zend_Db_Select but it gives me array error
$select->from($dao, array('groups.name', 'categories.name', 'categories.label'))
->join(array('categories', 'categories.group1 = groups.id OR categories.group2 = groups.id'))
->where('groups.label = ?', $group)
->where('categories.active = 1');
My error:
Exception information:
Message: Select query cannot join with
another table
Does anyone know what I did wrong?
UPDATE / SOLUTION:
I've found the solution thanx to Eran. I just post the solution here in case anyone else is stuck on a problem like this one. The solution is:
$db = Zend_Registry::get('db');
$dao = new Default_Model_Db_CategoryDao('db');
$select = $dao->select();
$select->setIntegrityCheck(false)
->from(array('c' => 'categories'), array('name', 'label'))
->join(array('g' => 'groups'), 'c.group1 = g.id OR c.group2 = g.id', 'g.label')
->where('g.label = ?', $group)
->where('c.active = 1');
return $dao->fetchAll($select);
You are using a Zend_Db_Table_Select object. Those by default have integrity check enabled and cannot select data that is outside of their table.
You can turn it off by adding -> setIntegrityCheck(false) to the select object before querying with it.
You can read more about it in the manual under Select API -> Advanced usage

Categories