How to order including word order in SQL - mysql

Here is my query:
$select = $this->_conn->select();
$select->from(array('usr' => $this->_prefix . 'user'));
$select->join(array('rol' => 'role'), 'usr.role_id = rol.role_id',array());
$select->join(array('law' => 'lawyer_details'), 'usr.user_id = law.user_id', array('lawyer_url'));
$select->where("usr.user_status = ?","yes");
$select->where("rol.role_key = ?","yes");
$select->where("usr.user_section_show = ?","yes");
$select->where("usr.managment_show = ?","yes");
$select->limit(4);
$select->order(array('usr.user_firstname ASC'));
$rs = $select->query()->fetchAll();
return new Obt_Model_RecordSet($rs, $this);
I want to order by user_firstname but first get that user which names are "xxx","yyy","lll";

->order(new Zend_Db_Expr("FIELD(usr.user_firstname, 'xxx','yyy','lll')"));

Try this :-
order by (user_firstname='xxx') DESC,user_firstname ASC

In standard SQL, you may use:
order by
(case when usr.user_firstname in ('xxx', 'yyy', 'III') then 1 else 0 end) DESC,
usr.user_firstname ASC

Related

Subquery By Zend Database Format

I created a query in MYSQL as follows :
select subsql.item_id, subsql.uid, subsql.post_date, subsql.uid_prev,
max(workflow_trans.date) AS pre_date
from (
select item_id, max(date) AS post_date, uid, uid_prev
from workflow_trans
where uid = 'name' and date <= 'date1' and date >= 'date2'
group by item_id, uid, uid_prev
) AS subsql
left join workflow_trans on subsql.item_id = workflow_trans.item_id and
subsql.uid_prev = workflow_trans.uid and subsql.post_date > workflow_trans.date
where workflow_trans.date is not null
group by subsql.item_id, subsql.uid, subsql.post_date, subsql.uid_prev
order by subsql.post_date
The In translated it to Zend DB format as follows :
$this->db->select()->from(array("subsql" => $this->db->select()
->from(array($this->_name), array('item_id', 'max(date) AS post_date',
'uid', 'uid_prev'))
->where("uid = ?", $username)->where("date >= ?", $tgl1)
->where("date <= ?", $tgl2)
->group(array('item_id', 'uid', 'uid_prev'))),
array('subsql.item_id','subsql.uid',
'subsql.post_date','subsql.uid_prev','max(workflow_trans.date)
as pre_date'))
->joinLeft($this->_name, 'subsql.item_id = workflow_trans.item_id
and subsql.uid_prev = workflow_trans.uid and subsql.post_date >
workflow_trans.date')
->where("workflow_trans.date != ?", null)
->group(array('subsql.item_id', 'subsql.uid', 'subsql.post_date',
'subsql.uid_prev'))
->order(array('subsql.post_date'))
Yet the Zend model could not working. i've been reexamined it, and made 3 changes, but still there is something wrong with the formatting. Fresh pair of sharp eyes are appreciated.
ANSWER UPDATE
Hello guys, I already found it, below the running code :
$this->db->select()->from(array("subsql" => $this->db->select()
->from(array($this->_name), array('item_id', 'max(date) AS post_date',
'uid', 'uid_prev'))
->where("uid = ?", $username)->where("date >= ?", $tgl1)
->where("date <= ?", $tgl2)
->group(array('item_id', 'uid', 'uid_prev'))),
array('subsql.item_id','subsql.uid','subsql.post_date','subsql.uid_prev'))
->joinLeft(array($this->_name), 'subsql.item_id = workflow_trans.item_id and
subsql.uid_prev = workflow_trans.uid and
subsql.post_date > workflow_trans.date',
array('max(workflow_trans.date) as pre_date'))
->where("workflow_trans.date is not null")
->group(array('subsql.item_id', 'subsql.uid', 'subsql.post_date',
'subsql.uid_prev'))
->order(array('subsql.post_date'));
You should define the column from joining table in its own join function, and of course I got it wrong on how to handle the null.
If we talks about zf3, this query generates same sql as with yours.
$from = $this->getSql()->select('workflow_trans')
->columns(['item_id, max(date) AS post_date, uid, uid_prev', new Literal('max(workflow_trans.date) AS pre_date')])
->where(['uid = ?' => 'name'])
->where(['date <= ?' => 'date1'])
->where(['date >= ?' => 'date2'])
->group(['item_id', 'uid', 'uid_prev']);
$query = $this->getSql()->select()
->columns(['item_id, uid, post_date, uid_prev'])
->from(['subsql' => $from])
->join('workflow_trans', 'subsql.item_id = workflow_trans.item_id and subsql.uid_prev = workflow_trans.uid and subsql.post_date > workflow_trans.date', [])
->where(new IsNotNull('workflow_trans.date'))
->group(['subsql.item_id', 'subsql.uid', 'subsql.post_date', 'subsql.uid_prev'])
->order('subsql.post_date');

Field Name 'order' clashes with mysql with Zend_Db_table_Abstract?

unfortunately I created the table with a field name called order.
Is there a way to change the query builder to make sure the field name is encased in the ` (apostrophe's)
My query is as follows:
$select = $this->select();
$select->order('order DESC');
$select->where('order < ?', $row->menu_id);
$select->where('menu_id = ?', $row->menu_id);
The builder creates:
SELECT `menu_items`.*
FROM `menu_items`
WHERE (order < '1')
AND (menu_id = '1')
ORDER BY `order` DESC LIMIT 1
I would like it to create
SELECT `menu_items`.*
FROM `menu_items`
WHERE (`order` < '1')
AND (menu_id = '1')
ORDER BY `order` DESC LIMIT 1
thanks
I'm no expert but according to the docs
No quoting is applied to expressions given to the where() or orWhere() methods. If you have column names that need to be quoted, you must use quoteIdentifier() as you form the string for the condition.
There is an example of using quoteIdentifier() in the section "Adding Expression Columns":
$select = $db->select()
->from(array('p' => 'products'),
array('origin' =>
'(p.' . $db->quoteIdentifier('from') . ' + 10)')
);
So you need to do something like this:
$db = Zend_Db_Table::getDefaultAdapter();
$select = $this->select();
$select->order('order DESC');
$select->where($db->quoteIdentifier('order') . ' < ?', $row->menu_id);
$select->where('menu_id = ?', $row->menu_id);
Note that in the order() method,
column names are quoted as identifiers, unless they contain parentheses or are an object of type Zend_Db_Expr.
so you don't have to do anything special there.

Rails3 NOT IN query takes string as a value

I am trying to select users who don't have post in the forum list. For that I wrote a query like this
users_id = Post.where(:forum_id => 1).collect { |c| c.user_id }
#users = User.where('topic_id = ? and id not in ? ', "#{#topic.id}", "#{users_id}")
This code throws mysql error, and in my log
SELECT `user`.* FROM `user` WHERE (forum_id = '2222' and id not in '[5877, 5899, 5828, 5876, 5841, 5838, 5840, 5882, 5881, 5870, 5842, 5843, 5844, 5845, 5889, 5896, 5869, 5847, 5849, 5850, 5855, 5857, 5859, 5867, 5861, 5863, 5865, 5868, 5829, 5830, 5831, 5832, 5833, 5900, 6326, 6326, 6332, 5898, 6333, 6334, 6335, 6336, 6339, 7034, 7019, 6336, 5887, 5827, 9940, 9943, 9949, 7030, 9979, 9980, 5892, 9896, 14208, 14224, 14281, 14282, 14283, 5894, 5895, 14689, 14717]'
In mysql I execute the following query, and got the expected result
select * from users where topic_id = 1 and id not in (select users_id from posts where forum_id = 1);
The above query in rails doesn't seem to work..
Try this:
users_ids = Post.where(:forum_id => 1).collect { |c| c.user_id }
#users = User.where('topic_id = ? and id not in (?) ', #topic.id, users_ids)
Also, I advice you to make some changes:
Use pluck instead of collect (pluck is on the DB level)(pluck doc ; pluck vs. collect)
users_ids = Post.where(:forum_id => 1).pluck(:user_id)
name the table in the where clause to avoid ambiguous calls (in where chaining for example):
User.where('users.topic_id = ? AND users.id NOT IN (?)', #topic.id, users_ids)
The final code:
users_ids = Post.where(:forum_id => 1).pluck(:user_id)
#users = User.where('users.topic_id = ? AND users.id NOT IN (?)', #topic.id, users_ids)

an SQL query in LINQ

I have a table with these columns: CombinationID, IndexID, Value
There is a sql query:
SELECT CombinationID
FROM CombinationIndex
where IndexID <> 4
group by CombinationID
order by sum(case indexid when 1 then -Value else Value end) desc
How could I write this query in c# by linq?
I think this should just about do it for you (it's all off the top of my head so there could be slight syntactical errors):
var results = context
.CombinationIndexes
.Where(i => i.IndexID != 4)
.GroupBy(i => i.CombinationID)
.OrderBy(g => g.Sum(i => i.IndexID == 1 ? -i.Value : i.Value))
.Select(g => g.Key);

Dynamic mysql query LIMIT not working

I'm creating the parameters to LIMIT a mysql query using PHP variables. I'm outputting the query to make sure it's right, and it is. However the results completely ignore the offset parameter. However if I manually type in the LIMIT, it works fine.
$page_rows = 5;
$max = ($pagenum - 1) * $page_rows .',' .$page_rows;
$qry = "SELECT * FROM ".$wpdb->prefix."nslikethis_votes WHERE user_id = '$uid' AND active = 1 ORDER BY time DESC LIMIT " . $max;
$rs = mysql_query($qry);
$result = array();
if($rs && $rows>0){
while($lc = mysql_fetch_object($rs, "LikedContent")){
$result[] = $lc;
}
}
return $result;
Outputting $qry gives me this whether I use $max or manually enter '5,5':
SELECT * FROM wp_nslikethis_votes WHERE user_id = '1' AND active = 1 ORDER BY time DESC LIMIT 5,5
Try doing this for check:
$page_rows = "5";
$max = ($pagenum - 1) * $page_rows .',' .$page_rows;
$qry = "SELECT * FROM ".$wpdb->prefix."nslikethis_votes WHERE user_id = '$uid' AND `active` = 1 ORDER BY `time` DESC LIMIT " . $max;
//check for variables in query like $wpdb->prefix, $uid: are they fine, and try adding tilded sign as above
Hope this works for you