2017-09-01 121 views
1

我有一个4列的表。我想根据输入显示行,并且应该能够根据优先级字段优先显示。如何确定结果的优先级laravel雄辩

例如:我的表看起来像这样:

ID title   description tags 
1 web developer designer  front-end 
2 designer  front-end  web developer 
3 front-end  web developer designer 

我有我的测试用例低于它应该是如何工作的:

$input = 'web developer' // the sequence should be IDs : 1, 3, 2 
$input = 'front-end'  // output sequence result is : 3, 2, 1 
$input = 'designer'  // result sequence : 2, 1, 3 

现在,我想要的结果,从标题到标签优先基于输入。

$blog = DB::('blogs') 
     ->where('title', 'LIKE', '%$title%') 
     ->where('description', 'LIKE', '%$title%') 
     ->where('tags', 'LIKE', '%$title%'); 

但上面的代码,似乎它没有..

回答

1

没有很好的解决,但是这可能会帮助你,

$input = 'web developer'; 

$byTitle = DB::('blogs') 
      ->where('title', 'LIKE', '%$input%') 
      ->select('id'); 

$byDescription = DB::('blogs') 
       ->where('description', 'LIKE', '%$input%') 
       ->select('id'); 

$byTag = DB::('blogs') 
     ->where('tag', 'LIKE', '%$input%') 
     ->select('id'); 

$ids = $byTitle->union($byDescription)->union($byTag)->get(); 

您可以根据栏,然后选择ID他们结合获取数据。

这里是一个原始查询会是什么样子,如果你想通过UNION来处理这个问题:

SELECT ID, 1 AS priority 
FROM blogs 
WHERE title = 'web developer' 
UNION 
SELECT ID, 2 
FROM blogs 
WHERE description = 'web developer' 
UNION 
SELECT ID, 3 
FROM blogs 
WHERE tags = 'web developer' 
ORDER BY 
    priority, 
    ID 

一个需要注意这里要说的是,如果给定的记录有相同的值,两个或两个以上的称号,说明或标签列,那么最终会出现重复记录出现在结果集中。从您的原始数据看,这似乎没有发生,尽管这是一个值得一提的边缘案例。

+0

你有逻辑的人,但我认为这会工作过慢,如果你有几百万个数据的 – smzapp

+0

我想你也将需要一个'ORDER BY'条款在这里做这个工作。您可以将一个计算列添加到您的'UNION'查询中,以跟踪每个子查询,然后在最后按该列排序。 –

+0

@samuel是的绝对,这就是为什么我提到“不是一个好的解决方案” –

4

我认为您要订购结果的逻辑应该出现在ORDER BY条款中。考虑下面的原始查询:

SELECT * 
FROM yourTable 
ORDER BY 
    CASE WHEN title = 'web developer'  THEN 0 ELSE 1 END, 
    CASE WHEN description = 'web developer' THEN 0 ELSE 1 END, 
    CASE WHEN tags = 'web developer'  THEN 0 ELSE 1 END; 

输出:

enter image description here

这是我在什么Laravel代码看起来像使用orderByRaw尝试:

$orderByClause = "CASE WHEN title = '".$input."' THEN 0 ELSE 1 END,"; 
$orderByClause .= "CASE WHEN description = '".$input."' THEN 0 ELSE 1 END," 
$orderByClause .= "CASE WHEN tags = '".$input."' THEN 0 ELSE 1 END" 

$blog = DB::('blogs') 
     ->orderByRaw($orderByClause) 
     ->get(); 

我不能找不到关于如何参数化orderByRaw的任何(工作)文档,所以我使用了字符串连接。

演示在这里:

Rextester