Different approach for pagination - LIMIT when using SQLSRV - pagination

I'm trying to make an instant pagination using SQLSRV and PHP, I have successfully did this using MySQL but unable to do so when using SQL Server as it does not support LIMIT.
I have the following codes working in MySQL and I wanted to apply the same thing in sqlsrv but since this is not possible, I'm looking forward in creating a different approach(code) to achieve this, can someone give me an idea or a walkthrough to make this happen please, thanks in advanced.
if(isset($_POST['page'])):
$paged=$_POST['page'];
$sql="SELECT * FROM `member` ORDER BY `member`.`member_id` ASC";
if($paged>0){
$page_limit=$resultsPerPage*($paged-1);
$pagination_sql=" LIMIT $page_limit, $resultsPerPage";
}
else{
$pagination_sql=" FETCH 0 , $resultsPerPage";
}
$result=sqlsrv_query($sql.$pagination_sql);

Try the following code, I hope you find it helpful
$paged = filter_input(INPUT_POST, 'page', FILTER_SANITIZE_NUMBER_INT);
//Initialize these values
$Table = 'your_tbl_name'; //Table name
$IndexColumn = 'pk_col_name'; //Primary key column
$resultsPerPage = '10'; //Page size
$Where = ''; //Optional WHERE clause, may leave empty
$Order = ''; //Optional ORDER clause, may leave empty
$top = ($paged>0) ? $resultsPerPage * ($paged-1) : 0 ;
$limit = 'TOP ' . $resultsPerPage ;
$pagination_sql = "SELECT $limit *
FROM $Table
$Where ".(($Where=="")?" WHERE ":" AND ")." $IndexColumn NOT IN
(
SELECT $IndexColumn FROM
(
SELECT TOP $top *
FROM $Table
$Where
$Order
)
as [virtTable]
)
$Order";
$result=sqlsrv_query($conn, $pagination_sql);

Related

laravel 5 - paginate total() of a query with distinct

I have a query to get photos according to values in a pivot table, that stores the relation of "pics" and "tags":
#photos
$q = PicTag::select(DB::raw('distinct(pics.id)'),
'pics.url',
'pics.titel',
'pics.hits',
'pics.created_at',
'users.username',
'users.displayname')
->leftJoin('pics', 'pics.id', '=', 'pic_tag.pic_id')
->leftJoin('users','users.id','=','pics.user_id')
->whereIn('pic_tag.tag_id', $tagids);
if($cat)
$q->where('typ',$cat);
if($year)
$q->where('jahrprod',$year);
$pics = $q->orderBy('pics.id','desc')
->paginate(30);
The problem is, when for a certain photo multiple (same) tags are stored like "Tag", "tag" and "tAG". Then the same photo would be shown 3 times in my gallery. That is why I use the distinct in the query.
Then the gallery is ok, but $pics->total() does not show "87 photos" but for example "90 photos", because the distinct is not used in the pagination. In laravel 4, I used groupBy('pics.id'), but this did not seem to be the fastest query and with laravel 5 it gives me a total() count result of 1.
How could I get the right total() value?
I know it's an old subject but it could help some other people.
I faced the same problem and the only good solution (low memory cost) I found was to do the request in two times:
$ids = DB::table('foo')
->selectRaw('foo.id')
->distinct()
->pluck('foo.id');
$results = $query = DB::table('foo')
->selectRaw('foo.id')
->whereIn('foo.id', $ids)
->paginate();
I tried this with 100k results, and had no problem at all.
Laravel has issue in paginate of complex queries. so you should handle them manually . In laravel 5 I did it in 2 steps :
Step 1: repository method :
public function getByPage($page = 1, $limit = 10 , $provinceId , $cityId , $expertiseId)
{
$array = ['users.deleted' => false];
$array["users.approved"] = true;
$array["users.is_confirmed"] = true;
if($provinceId)
$array["users.province_FK"] = $provinceId;
if($cityId)
$array["users.city_FK"] = $cityId;
if($expertiseId)
$array["ONJNCT_USERS_EXPERTISE.expertise_FK"] = $expertiseId;
$results = new \stdClass();
$results->page = $page;
$results->limit = $limit;
$results->totalItems = 0;
$results->items = array();
$users= DB::table('users')
->distinct()
->select('users.*','ONDEGREES.name as drgree_name')
->join('ONJNCT_USERS_EXPERTISE', 'users.id', '=', 'ONJNCT_USERS_EXPERTISE.user_FK')
->join('ONDEGREES', 'users.degree_FK', '=', 'ONDEGREES.id')
->where($array)
->skip($limit * ($page - 1))->take($limit)->get();
//$users = $usersQuery>skip($limit * ($page - 1))->take($limit)->get();
$usersCount= DB::table('users')
->select('users.*','ONDEGREES.name as drgree_name')
->join('ONJNCT_USERS_EXPERTISE', 'users.id', '=', 'ONJNCT_USERS_EXPERTISE.user_FK')
->join('ONDEGREES', 'users.degree_FK', '=', 'ONDEGREES.id')
->where($array)
->count(DB::raw('DISTINCT users.id'));
$results->totalItems = $usersCount;
$results->items = $users;
return $results;
}
Step 2:
In my Search Controller :
function search($provinceId , $cityId , $expertiseId){
$page = Input::get('page', 1);
$data = $this->userService->getByPage($page, 1 , $provinceId ,$cityId , $expertiseId);
$users = new LengthAwarePaginator($data->items, $data->totalItems, 1 , Paginator::resolveCurrentPage(),['path' => Paginator::resolveCurrentPath()]);
return View::make('guest.search.searchResult')->with('users' ,$users);
}
It worked for me well!

Drupal 7 - Ubercart - Attributes in Views Fields

I have products that have attributes for 'color' & 'strength'. I'm trying to get those options listed under those attributes as fields for views, so that I can use them as filters. So for example sort by color & strength.
I've looked all around on google and can only find modules for Drupal 6. Anyone know of anything for 7?
Like said in the previous post I had 2 attributes 'color' & 'strength' which I needed to match for exact product matches but ubercart didn't have anything for that, so I wrote them into URL for get statements as variables 1 & 2, so for example a URL which had both attributes selected would look like:
www.website.com/node/68?1=96&2=7
Sometimes one variable would be set but not the other, so I had to make up for that also by using a % wildcard. Here's the code for that part
// Since PHP's serialize function sometimes serializes in the incorrect order,
// here we manually build the comparison key
// Additionally append the image links urls with provided strength/color data
if( isset( $_REQUEST['1'] ) ) {
$_1 = $_REQUEST['1'];
if( $_1 !== '%' ) $url[] = "1=$_1";
} else $_1 = '%';
if( isset( $_REQUEST['2'] ) ) {
$_2 = $_REQUEST['2'];
if( $_2 !== '%' ) $url[] = "2=$_2";
} else $_2 = '%';
$combination = "a:2:{i:1;s:";
$combination .= $_1 == '%' ? '%:"%";' : strlen($_1) . ':"' . $_1 . '";';
$combination .= "i:2;s:";
$combination .= $_2 == '%' ? '%:"%";' : strlen($_2) . ':"' . $_2 . '";';
$combination .= '}';
// if some products don't have a second attribute at all
$combination2 = "a:1:{i:1;s:";
$combination2 .= $_1 == '%' ? '%:"%"' : strlen($_1) . ':"' . $_1 . '";';
$combination2 .= ';}';
Underneath that I had to do some extra queries like if a taxonomy was set and check if some dynamic properties were set, thats why the WHERE is stored in a variable. Frankly they'll just confuse anyone so I left them out. But for your sake the next part you just need to query it.
$where = "WHERE (pa.combination LIKE :pattern1 OR pa.combination LIKE :pattern2) AND s.stock IS NOT NULL";
$comparison = array( ':pattern1' => $combination,
':pattern2' => $combination2 );
$filtered = db_query(
"
SELECT pa.nid, pa.model, pa.combination, n.title, p.sell_price, f.uri
FROM {uc_product_adjustments} pa
LEFT JOIN {node} n ON pa.nid = n.nid
LEFT JOIN {uc_products} p ON pa.nid = p.nid
LEFT JOIN {field_data_uc_product_image} i ON i.entity_type = 'node' AND i.entity_id = n.nid
LEFT JOIN {file_managed} f ON f.fid = i.uc_product_image_fid
LEFT JOIN {uc_product_stock} s ON pa.model = s.sku AND s.stock <> '0'
$where
",
$comparison
);
Lastly loop over the results and store them in a normal array
foreach( $filtered as $i => $record ) {
if( is_int( array_search( $record->nid, $nids ) ) ) continue;
else {
$nids[] = $record->nid;
$result[] = $record;
}
}
This code checks for any products that match any of the attribute values that are currently in stock
You may have a look at these sandbox projects : UC Views Attributes Work and UC attribute views.
I'm looking for a similar feature, as it seems not possible to get UC attributes into a view. I cannot test myself right now as I have a deadline this weekend for a project, but I'd be happy to have your feedback.

Zend_Search_Lucene - weird behaviour for Wildcard search and "numeric" string

Weird issue I get every time I search "11.11" or "22.22" etc... No problem if I search for "aa.aa" but when I put only integers into my string, I get the following exception:
Wildcard search is supported only for non-multiple word terms
My implementation of Zend search is as below (ZF 1.11):
Zend_Search_Lucene_Search_Query_Wildcard::setMinPrefixLength(0);
Zend_Search_Lucene_Search_QueryParser::setDefaultEncoding('utf-8');
Zend_Search_Lucene_Analysis_Analyzer::setDefault(
new Zend_Search_Lucene_Analysis_Analyzer_Common_Utf8Num_CaseInsensitive()
);
$index = Zend_Search_Lucene::open(APPLICATION_PATH.'/../var/search');
if(str_word_count($searchQuery) > 1){
$searchQuery = Zend_Search_Lucene_Search_QueryParser::escape($searchQuery);
$searchQueryArray = explode(' ', $searchQuery);
$query = new Zend_Search_Lucene_Search_Query_Phrase($searchQueryArray);
}else{
$searchQuery = Zend_Search_Lucene_Search_QueryParser::escape($searchQuery);
$query = Zend_Search_Lucene_Search_QueryParser::parse(
'title:*'.$searchQuery.'* OR
description:*'.$searchQuery.'* OR
content:*'.$searchQuery.'*'
);
}
$result = $index->find($query);
I can't really find any related issue on internet so please, let me know if you've ever been in front of the similar issue. Thank you.

expressionengine database class orderby and sort

How do we sort using the database class in expressionengine. orderby and sort are given an error and do not seem to work. I can't seem to find anything in the documantation about sorting results. This is what i have.
$results = $this->EE->db->query("
SELECT plan_name
FROM exp__plans
WHERE member_id='1002' AND orderby="id" sort="desc" LIMIT 1
");
$x = $results->row('plan_name')
;
There are issues with your query.
try:
$results = $this->EE->db->query("
SELECT plan_name
FROM exp_plans
WHERE member_id = '1002'
ORDER BY id DESC LIMIT 1
");
I would recommend trying to run your query directly against the database if you're having trouble with it. 90% of the time it will be an issue with your SQL.
Also, you are writing this in a add-on... right? if you're trying to get this to work within a template I would recommend checking out the query module.
You can also use Active Record in order to create your query:
$this->EE->db->select('plan_name')
->from('plans')
->where('member_id', '1002')
->order_by("id", "desc")
->limit(1)
->get();
All the doc is on the Codeigniter website.

Searching phpbb's 'topic_title' via MYSQL php, but exact match doesn't work

$sql = sprintf( "SELECT topic_title
FROM `phpbb_topics`
WHERE `topic_title` LIKE '%%%s%%' LIMIT 20"
, mysql_real_escape_string('match this title')
);
Which I run this query in phpMyAdmin the results are: (correct)
match this title
match this title 002
But when I run that same MYSQL query in PHP I get: (incorrect)
match this title 002
I have also tried MATCH AGAINST with the same result with both php and phpMyAdmin:
$sql = "SELECT topic_title
FROM phpbb_topics
WHERE MATCH (topic_title)
AGAINST('match this title' IN BOOLEAN MODE)";
The whole block of code im using to search with:
mysql_connect("localhost", "user", "pass") or die(mysql_error());
mysql_select_db("phpbb") or die(mysql_error());
$query = "match this title";
$query = "SELECT topic_title
FROM phpbb_topics
WHERE MATCH (topic_title)
AGAINST('$query' IN BOOLEAN MODE)";
// Doesn't work (these 2 both give the same result "match this title 002" and no the "match this title")
// $query = "SELECT * FROM `phpbb_topics`
// WHERE `topic_title`
// LIKE '%$query%'
// LIMIT 0, 30 "; // Doesn't work
$result = mysql_query($query) or die(mysql_error());
$row = mysql_fetch_array($result) or die(mysql_error());
while($row = mysql_fetch_array($result)){
$topic_title = $row['topic_title'];
echo "$topic_title";
}
Any idea as to what i'm doing wrong?
I'v been searching all over the place and have found next to no help :(
The problem is that after you execute your query you fetch the first row, do nothing with it, enter the loop by fetching the second row and start printing results..
If you remove the first $row = mysql_fetch_array($result), (directly after $result = mysql_query($query) or die(mysql_error());) you should be fine.
Another comment; If you echo a variable you don't have to put any qoutes around it. And in the way you're doing it now, you won't get a newline between the results so you might want to change that line to echo $topic_title . "<br>";

Resources