2014-07-22 28 views
1

为了结果我有一个看起来像这样的表:Zend的SQL语句来查找和occurances

 
ID | name | phone_number | date 
1 | bob | 4567   | 1/1/2011 
2 | bob | 8912   | 1/1/2010 
3 | bob | 1234   | 1/1/2010 
4 | bob | 1234   | 1/1/2014 
5 | bow | 4567   | 1/1/2014 

我创建一个自动提示,以便用户键入的名字就会拿起以前的名字和电话数字。由于人们可以更改他们的电话号码,我想要订购结果并根据最常用的电话号码显示号码的数量。作为第二种,它应该基于名称和添加日期的最后一种(最新的第一种)。

因此,如果有人类型的“博”,它应该返回:

 
bob 1234 (2) - Because it is alphabetically highest plus has the most phone numbers. 
bob 4567 (1) - Because it is alphabetically highest and its last entry is newer. 
bob 8912 (1) - Because it is alphabetically highest and its last entry was older. 
bow 4567 (1) - Because it is alphabetically lower. 

通常我会用例如Zend的方法:

public function getAllNames($part) 
{ 
    $select = $this->select(); 
    $select->where('name LIKE ?', '%'.$part.'%') 
      ->order('name'); 
    return $this->fetchAll($select)->toArray(); 
} 

但我被困在如何计算的项电话号码,然后执行三个命令。

或者只是获取所有条目并使用PHP来处理结果并相应地排序它会更好吗?

+0

我SQL。我不知道2011年1月1日是什么。 :-( – Strawberry

+0

对不起,该表有点弥补,人的表示(日期也是如此),日期是真实DB中的时间戳;-) – Scoobler

+0

人类?所以没有订阅你的日期格式的人不是人类;-) – Strawberry

回答

1

以下情况如何?

public function getAllNames($part) 
{ 
    $select = $this->select(); 
    $select->where('name LIKE ?', '%'.$part.'%') 
      ->order('name') 
      ->order(new \Zend\Db\Sql\Expression('LENGTH(phone_number)')) 
      ->order('date desc'); 
    return $this->fetchAll($select)->toArray(); 
} 

修订ANSWER

public function getAllNames($part) 
{ 
    $select = $this->select(); 
    $select->where('name LIKE ?', '%'.$part.'%') 
      ->group('name') 
      ->group('phone_number') 
      ->order('name') 
      ->order(new \Zend\Db\Sql\Expression('count(phone_number) DESC')) 
      ->order(new \Zend\Db\Sql\Expression('max(date) DESC')); 
    return $this->fetchAll($select)->toArray(); 
} 

另一个更新:使用MAX(日期)是没有必要的

public function getAllNames($part) 
{ 
    $select = $this->select(); 
    $select->where('name LIKE ?', '%'.$part.'%') 
      ->group('name') 
      ->group('phone_number') 
      ->order('name') 
      ->order(new \Zend\Db\Sql\Expression('count(phone_number) DESC')) 
      ->order('date DESC'); 
    return $this->fetchAll($select)->toArray(); 
} 
+0

这不仅仅是试图对电话号码中的字符数进行排序吗?它也不会阻止重复被返回? – Scoobler

+0

哦,是啊,我误解了'大多数电话号码',有点傻,想知道目的是什么......让我回到你这里:) – malte

+0

好吧,纠正了答案,我做了一个快速的测试案例和它似乎返回正确的结果...希望这可以帮助;) – malte

0

如果我理解正确的话......

DROP TABLE IF EXISTS my_table; 

CREATE TABLE my_table 
(ID INT NOT NULL AUTO_INCREMENT PRIMARY KEY 
,name VARCHAR(12) NOT NULL 
,phone_number VARCHAR(12) NOT NULL 
,date DATE NOT NULL 
); 

INSERT INTO my_table VALUES 
(1 ,'bob','4567','2011-01-01'), 
(2 ,'bob','8912','2010-01-01'), 
(3 ,'bob','1234','2010-01-01'), 
(4 ,'bob','1234','2014-01-01'), 
(5 ,'bow','4567','2014-01-01'); 


SELECT x.* 
     , y.total 
    FROM my_table x 
    JOIN 
     (SELECT name 
      , phone_number 
      , MAX(date) n_date 
      , COUNT(*) total 
      FROM my_table 
     WHERE name LIKE 'bo%' 
     GROUP 
      BY name 
      , phone_number 
    ) y 
    ON y.name = x.name 
    AND y.phone_number = x.phone_number 
    AND y.n_date = x.date 
    ORDER 
    BY x.name 
     , y.total DESC 
     , x.date DESC; 
+----+------+--------------+------------+-------+ 
| ID | name | phone_number | date  | total | 
+----+------+--------------+------------+-------+ 
| 4 | bob | 1234   | 2014-01-01 |  2 | 
| 1 | bob | 4567   | 2011-01-01 |  1 | 
| 2 | bob | 8912   | 2010-01-01 |  1 | 
| 5 | bow | 4567   | 2014-01-01 |  1 | 
+----+------+--------------+------------+-------+ 
1

这是我实际使用的答案,感谢user3511578。正如在评论中,我没有在我的Zend库表达模块,所以我做了这样的:

万一它有助于任何人在未来:

public function getAllNames($part) 
{ 
    $select = $this->select(); 
    $select->from($this->_name, array('name', 'phone_number', 'count'=>'COUNT(phone_number)')) 
      ->where('name LIKE ?', '%'.$part.'%') 
      ->group('name') 
      ->group('number') 
      ->order('name') 
      ->order('count DESC') 
      ->order('date desc'); 
    return $this->fetchAll($select)->toArray(); 
}