I have an sql query like the one below and i would like to create this in Zend Framework 2.
( SELECT id AS id FROM exp_personal_data ORDER BY town ) UNION ( SELECT id AS id FROM pd_unregister )
I would like to have union and add to this LIMIT, ORDER BY etc.
$this->_select->combine($selectPdContest, 'union all');
When i write the query like this.
$this->_select->combine($selectPdContest, 'union all')->limit('10);
Query looks like this:
( SELECT id AS id FROM exp_personal_data ORDER BY town LIMIT 10 ) UNION ( SELECT id AS id FROM pd_unregister )
The limit is added only to firs select. I want the limit will to be added like this.
( SELECT id AS id FROM exp_personal_data ORDER BY town ) UNION ( SELECT id AS id FROM pd_unregister ) LIMIT 10
How make this in Zend framework 2?
Solution 1 (simple):
$adapter = $this->tableGateway->getAdapter();
$resultSet = $adapter->query("(SELECT user_id AS id FROM user ORDER BY id) UNION (SELECT account_id AS id FROM account) LIMIT 10",$adapter::QUERY_MODE_EXECUTE);
print_r($resultSet->toArray());die;
Solution 2 (Complex):
use Zend\Db\Sql\Sql;
use Zend\Db\Sql\Select;
//sql query first part
$adapter = $this->tableGateway->getAdapter();//the db connection adapter
$select = new Select('user');
$select->columns(array('id' => 'user_id'));
$select->order('id');
$sql = new Sql($adapter);
$statement = $sql->getSqlStringForSqlObject($select);
//sql query second part
$select2 = new Select('account');
$select2->columns(array('id' => 'account_id'));
$sql = new Sql($adapter);
$statement2 = $sql->getSqlStringForSqlObject($select2);
//combine the two statements into one
$unionQuery = sprintf('%s UNION %s','('.$statement = $sql->getSqlStringForSqlObject($select).')',
'('.$statement2 = $sql->getSqlStringForSqlObject($select2).') LIMIT 10');
//execute the union query
$resultSet = $adapter->query( $unionQuery, $adapter::QUERY_MODE_EXECUTE);
print_r($resultSet->toArray());die;
Add these lines will work,
$select1 = new Select();
$select1->combine($selectPdContest, 'union all');
$select3 = new Select();
$oneTwo = $select3->from(['sub' => $select1])->limit(10);
Related
I am trying to make next query with ActiveRecord and have no idea about how to achieve this SQL result without using find_by_sql call.
SELECT *
FROM table_x AS a,
(SELECT locator, max(day_parsed) AS max_day
FROM table_x
WHERE day_parsed BETWEEN params[:day_from] AND params[:day_to]
GROUP BY locator) AS b
WHERE a.locator = b.locator
AND a.day_parsed = b.max_day
Any idea?
For example, we have active record TableX and its table name is table_x, so the query will be:
from = params[:day_from]
to = params[:day_to]
TableX.joins("JOIN (
SELECT locator, max(day_parsed) AS max_day
FROM table_x
WHERE day_parsed BETWEEN #{from} AND #{to}
GROUP BY locator
) as b ON b.locator = table_x.locator")
.where("table_x.day_parsed = b.max_day")
How can I add a classname of "topseller" to the top sell products on woocommerce?
Is there a function that checks whether product is top sell?
I did. Here is the solution;
first I generated a query which gets 10 products that have biggest total_sales
$query = "SELECT ID FROM {$wpdb->posts} p
INNER JOIN {$wpdb->postmeta} pm ON ( pm.post_id = p.ID AND pm.meta_key='total_sales' )
WHERE p.post_type = 'product'
AND p.post_status = 'publish'
ORDER BY pm.meta_value+0 DESC
LIMIT 10";
$topselled_ids = $wpdb->get_results( $wpdb->prepare($query,OBJECT ));
//print_r ($topselled_ids );
foreach ($topselled_ids as $one_topselled_id)
$topselled[] = $one_topselled_id->ID;
Then I checked if id of current product is in array (in the content-product.php) .
if ( in_array($post->ID, $topselled) )
$classes[] = "top_selled";
I must be missing something obvious. The orderby cluase in this query has no effect on the order of the items displayed in my select list...
List<String> reps = (from r in db.bookings
where !r.bookingRep1.Contains("*") && !r.bookingRep1.Contains(" ")
orderby r.bookingRep1
select r.bookingRep1).Distinct().ToList();
ViewBag.rep1 = new SelectList(reps, booking.bookingRep1);
the select list...
#Html.DropDownListFor(model => model.bookings.bookingRep1, (SelectList)ViewBag.rep1, "")
I would like the select list to be ordered alphabetically by bookingrep1
Apply ordering after applying Distinct:
List<string> reps =
(from r in db.bookings
where !r.bookingRep1.Contains("*") && !r.bookingRep1.Contains(" ")
select r.bookingRep1).Distinct().OrderBy(rep => rep).ToList();
ViewBag.rep1 = new SelectList(reps, booking.bookingRep1);
When you apply Distinct to ordered query, then ordering just removed from generated SQL:
SELECT
[Distinct1].[bookingRep1] AS [bookingRep1]
FROM ( SELECT DISTINCT
[Extent1].[bookingRep1] AS [bookingRep1]
FROM [dbo].[bookings] AS [Extent1]
WHERE [Extent1].[bookingRep1] NOT LIKE #p1 AND
[Extent1].[bookingRep1] NOT LIKE #p2
) AS [Distinct1]
When ordering is applied after Distinct then its present in generated SQL:
SELECT
[Distinct1].[bookingRep1] AS [bookingRep1]
FROM ( SELECT DISTINCT
[Extent1].[bookingRep1] AS [bookingRep1]
FROM [dbo].[bookings] AS [Extent1]
WHERE [Extent1].[bookingRep1] NOT LIKE #p1 AND
[Extent1].[bookingRep1] NOT LIKE #p2
) AS [Distinct1]
ORDER BY [Distinct1].[bookingRep1] ASC
I want to make this query using Zend\Db\Sql\Select:
SELECT table1.* FROM table1
INNER JOIN table2 ON table1.columnA = table2.columnB
INNER JOIN table3 ON table1.columnC = table3.columnD
WHERE (table2.column2 = 2 or table3.column3 = 3) and table1.column1 = 1
ORDER BY table1.columnE ASC LIMIT 1
I have this code so far:
/*#var $db Adapter */
$db = $this->getServiceLocator()->get('db');
$sql = new Sql($db);
$select = $sql->select();
$select->from('table1');
$select->join('table2','table1.columnA = table2.columnB',array());
$select->join('table3','table1.columnC = table3.columnD',array());
$select->where(array('table2.column2' => 2, 'table2.column3' => 3), Predicate\PredicateSet::OP_OR);
$select->where(array('table1.column1' => 1),Predicate\PredicateSet::OP_AND);
$select->order('table1.columnE ASC');
$select->limit(1);
$statement = $sql->prepareStatementForSqlObject($select);
$resultSet = $statement->execute();
But doesn't works, because produce this one (without the "(" and ")" for the OR):
SELECT table1.* FROM table1
INNER JOIN table2 ON table1.columnA = table2.columnB
INNER JOIN table3 ON table1.columnC = table3.columnD
WHERE table2.column2 = 2 or table3.column3 = 3 and table1.column1 = 1
ORDER BY table1.columnE ASC LIMIT 1
What can I do?
from the top of the head using Where fluent interface:
$select->where
->nest
->equalTo('table2.column2', 2)
->or
->equalTo('table2.column3', 3)
->unnest
->and
->equalTo('table1.column1', 1);
I would do something like:
$where = new \Zend\Db\Sql\Where();
$where
->nest()
->equalTo('table2.column2', 2)
->or
->equalTo('table2.column3', 3)
->unnest()
->and
->equalTo('table1.column1', 1);
$select->where($where)
Just because this way your $select keep being an implementation of Zend\Db\Sql\SqlInterface
while doing
$select->where
->nest
will return an instance of a Zend Sql operator. Which is not bad but then you can't just do
$statement = $sql->prepareStatementForSqlObject($select);
$resultSet = $statement->execute();
I have this sql:
SELECT link.ID, link.URL, link.ANCHOR, link.HOME, link.CREATED_AT
FROM `link`, `linkcategory`
WHERE link.ID=linkcategory.LINK_ID
GROUP BY linkcategory.LINK_ID
HAVING count(linkcategory.category_id) =(select count(*) from categoria)
And I'm trying to generate the criteria, this is the criteria that doesn't work:
$c = new Criteria();
$c->addJoin(self::ID, LinkcategoryPeer::LINK_ID);
$c->addAsColumn('catCount','(SELECT COUNT(*) FROM CATEGORIA)');
$c->addGroupByColumn(LinkcategoryPeer::LINK_ID);
$having = $c->getNewCriterion(count(LinkcategoryPeer::CATEGORY_ID),$c->getColumnForAs('catCount'));
$c->addHaving($having);
return self::doSelect($c);
The returning sql of this criteria is this one:
SELECT (SELECT COUNT(*) FROM CATEGORIA) AS catCount
FROM `link`, `linkcategory`
WHERE link.ID=linkcategory.LINK_ID
GROUP BY linkcategory.LINK_ID
HAVING 1='(SELECT COUNT(*) FROM CATEGORIA)'
I really don't know why the criteria convert the sql incorrectly. Anyone knows where is the mistake?
Try with this query. I don't remember how to perform a link.* using Propel. But I think the problem with having is that you are using the PHP count function insteand of the MySQL one.
$c = new Criteria();
$c->addSelectColumn(self::ID);
$c->addSelectColumn(self::URL);
$c->addSelectColumn(self::ANCHOR);
$c->addSelectColumn(self::HOME);
$c->addSelectColumn(self::CREATED_AT );
$c->addJoin(self::ID, LinkcategoryPeer::LINK_ID);
$c->addGroupByColumn(LinkcategoryPeer::LINK_ID);
$having = $c->getNewCriterion(
'COUNT('.LinkcategoryPeer::CATEGORY_ID.')'),
$c->getColumnForAs('catCount')
);
$c->addHaving($having);
return self::doSelect($c);