how do laravel orderby string - php

I use the following code to display the record
$q = '[20,1,5,40,3]';
$qex = explode(",",$q);
$list = DB::table('mytable')->whereIn('id', $qex)->get();
I want show the result like this :
result :20 1 5 40 3
but my reslut is :
1 3 5 20 40
I do not want the result to be sorted based on the id and I want it to be sorted based on the input I gave($q).
thanks
My problem solved by this code :
$list = DB::table('mytable')
->whereIn('id', $qex)
->orderByRaw(\DB::raw("FIELD(id, ".implode(",",$qex).")"))
->get();

Related

How to sum up table rows group by storage_id and product_id

I am trying the following problem : I am sharing the table image first(from where the rows will be summed up)
When the api is Hit, It should first group the storage_id, then product_id and then sum up quanitity of same product_id
for example :
there are two storage_id : 1 & 2 , two different product_id : 1 & 2 . Now the output should be sum all the rows where storage_id, where product_id. there should be 3 JSON outputs, for storage 1 & product 1, for storage 1 & product 2. for storage 2 & product 2. And they should be then stored in a table like the following table
My code so far ( from the controller ) :
$storages = Storage::get(); // getting storage list
foreach($storages as $storage => $val){
$storage_id[] = $storages[$storage]->id; // Getting array of id only
$get_storage[] = Storage::with('storageProducts')->whereIn('id', $storage_id)->get();
foreach($get_storage as $product => $val){
foreach($val as $d){
$a[$d->id] = StorageProduct::where('transfer_type',1)
->where('storage_id',$d->id)
->groupBy('storage_id', 'product_id')
->sum('quantity');
}
}
}
The output I am getting :
{
"1": 28,
"2": 23
}
$result = StorageProduct::where('transfer_type',1)
->select('storage_id', 'product_id', DB::raw('SUM(quantity) as stock'))
->groupBy('storage_id', 'product_id')
->get();
SELECT storage_id , product_id ,SUM(stock) as stock FROM tb_stock GROUP BY product_id , storage_id

Codeigniter limit and offset pagination not working in descending order

Pagination worked fine in ASC order but I just can't get it to work in DESC order.
I have 10 test videos in my database with ids from 1-10, in the first batch I want to get the last 5 videos (ids: 10,9,8,7,6) and in the next batch the remaining ones (id:5,4,3,2,1).
The problem is that I always get empty results when using DESC order, here is my code:
$limit = 5;
$this->db->select('*');
$this->db->from('participant_videos');
$this->db->order_by('id','DESC');
$this->db->limit($limit,$index); // currently index is 10
$query=$this->db->get();
$videos = $query->result_array(); // empty array
echo $this->db->last_query();
// QUERY: SELECT * FROM `participant_videos` ORDER BY `id` DESC LIMIT 10, 5
return [
'videos' => $videos,
'index' => empty($videos) ? 0 : $index - $limit,
];
First time the index is determined like this:
public function get_latest_video () {
$video = $this->db->select("*")->limit(1)->order_by('id',"DESC")->get("participant_videos")->row_array();
return !empty($video['id']) ? $video['id'] : null; // index (10)
}
This is my table structure and content:
== Table structure for table participant_videos
|------
|Column|Type|Null|Default
|------
|//**id**//|int(11)|No|
|participant_id|int(11)|No|
|video_url|varchar(255)|No|
|video_type|varchar(255)|No|video/mp4
== Dumping data for table participant_videos
|2|2|/uploads/2-6138aef5a0717.mp4|video/mp4
|3|3|/uploads/3-6138b09449800.mp4|video/mp4
|4|4|/uploads/4-6138b0c3b1965.mp4|video/mp4
|5|5|/uploads/5-6138b0efa7aa1.mp4|video/mp4
|6|6|/uploads/6-6138b10667680.mp4|video/mp4
|7|7|/uploads/7-6138b154084a4.mp4|video/mp4
|8|8|/uploads/8-6138b1779bee0.mp4|video/mp4
|9|9|/uploads/9-613b4bc1e1d58.mp4|video/mp4
|10|16|/uploads/16-613b57a76c696.mp4|video/mp4
It turns out that offset "switches" sides when in DESC order, so instead of using biggest id as offset:
SELECT * FROM participant_videos ORDER BY id DESC LIMIT 10, 5
I had to change my offset to 0 to start from the biggest id:
SELECT * FROM participant_videos ORDER BY id DESC LIMIT 0, 5
This way I would recive the last 5 videos.

Laravel Query how to check if column starts with 0

I have a CRUD application with a Registration table and a Category table. In the RegistrationController, I use a query with Category, so I have made another query. I struggled with checking if every other gender_id has a cte_from that starts with 0. The cte_gender_id has 1, 2, or 3. 1 = man, 2 = women 3 = undetermined and nd cte_from are age ranges.
So in the database: cte_gender_id is 1 and cte_from is 0
then anther row cte_gender_id is 1 and cte_from is 25
then another cte_gender_id is 1 and 35
and so on but with gender_id 2 and 3.
RegistrationController
$gender_ids = ['1', '2', '3'];
foreach ($gender_ids as $gender_id) {
$category = Categorie::where('cte_distance_id', $distance_id)
->where('cte_gender_id', $gender_id)
->where('cte_from',)
->first();
if (is_null($category)) {
return back()->with("errorMessage", "Category not found");
}
}
So I want if, for example, where gender_id is 1 and cte_from doesn't start with 0, it already doesn't go through.
You can use WHERE cte_from LIKE '0%' to test if a string starts with 0. In this query, % is used for a wildcard.
Or in Laravel query builder:
->where('cte_from', 'LIKE', '0%')
// Or if it doesn't start with a 0
->where('cte_from', 'NOT LIKE', '0%')

Stuck with the same values when looping through database rows

I am trying to make a function where the following should happen:
Retrieve the ID value of all users in database.
Retrieve all numbers belonging to each user from an other table in the same database.
Add all the numbers belonging to each user together.
By using my code (see below), step 1 and 3 is working. At step 2, it is looping the correct amount of times but in every loop it retrieves the numbers belonging to the first ID from step 1.
Example:
Step 1 finds the following IDs: 1, 2, 3 and 4.
Step 2 loops 4 times, but retrieves the numbers belonging to ID 1 every time instead of retrieving the numbers to ID 1 in the first loop, ID 2 in the second etc.
My PHP:
$users_get = mysqli_query($conn,"SELECT id FROM users");
$users_num = mysqli_num_rows($users_get);
$users_list = array();
while($users_row = mysqli_fetch_array($users_get)){
$users_list[] = $users_row;
}
foreach($users_list as $users_row){
$users_items[] = array(
'id' => $users_row['id']
);
}
for($loop1 = 0; $loop1 < $users_num; $loop1++){
$numbers_get = mysqli_query($conn,"SELECT number FROM users_numbers WHERE userid = '".$users_items[$loop1]['id']."'");
$numbers_num = mysqli_num_rows($numbers_get);
$numbers_list = array();
while($numbers_row = mysqli_fetch_array($numbers_get)){
$numbers_list[] = $numbers_row;
}
foreach($numbers_list as $numbers_row){
$numbers_items[] = array(
'number' => $numbers_row['number']
);
}
$numbers_added = 0;
for($loop2 = 0; $loop2 < $numbers_num; $loop2++){
$numbers_added = $numbers_added + $numbers_items[$loop2]['number'];
}
}
I later added som echos to display the IDs and numbers that is retrieved and got the following result:
User ID: 1
Amount of numbers: 4
Numbers:
4 (Belonging to ID 1)
7 (Belonging to ID 1)
5 (Belonging to ID 1)
2 (Belonging to ID 1)
Total: 18
User ID: 2
Amount of numbers: 0
User ID: 3
Amount of numbers: 3
Numbers:
4 (Belonging to ID 1)
7 (Belonging to ID 1)
5 (Belonging to ID 1)
Total: 16
The amount of numbers for ID 3 is correct, however the 3 retrieved numbers belongs to ID 1.
Another observation I made was if I edit the SELECT query inside loop 1:
"SELECT number FROM users_numbers WHERE userid = '".$users_items[$loop1]['id']."'"
And manually selects an ID, example:
"SELECT number FROM users_numbers WHERE userid = '3'"
Then it retrieves the correct numbers belonging to ID 3.
After hours of trying to figure out what I'm doing wrong I still haven't found anything, so any help is really appreciated! Is there something I can do with my current code to fix it, or maybe there is some other ways to achieve the desired function?
Based on the comments on my question, I ended up with the following code:
$users_get = mysqli_query($conn,"SELECT a.id, SUM(b.number) AS number FROM users AS a INNER JOIN users_numbers AS b ON a.id = b.userid GROUP BY a.id ASC");
$loop1 = 0;
while($users_items[] = mysqli_fetch_array($users_get){
echo "ID: ".$users_items[$loop1]['id']." - Num total: ".$users_items[$loop1]['number']."<br />";
$loop1++;
}
The echo inside the while is only for testing purposes. When I run this, it displays a nice list with all the user IDs and the sum of each users numbers.

Unique value count of comma separated field (PHP - MySQL)

I have mysql table that looks like this:
id place interest
1 place1 a,b,c
2 place2 c,d,e
3 place1 a,e
4 place2 f
5 place2 f
6 place3 g,h
I need to get unique "place" and "interest" values sorted as per the count.
So, the output for "place" would be
place2(3)
place1(2)
place3(1)
So, the output for "interest" would be
a(2)
c(2)
e(2)
f(2)
b(1)
d(1)
g(1)
h(1)
is there a way to do this in PHP-Mysql?
So, far I have been able to get simple column data
SELECT place,
COUNT( * ) AS num
FROM testtab
GROUP BY place
ORDER BY COUNT( * ) DESC
As mysql is not able to hold arrays, its better to build a new table like this:
interest_id interest_name
1 a
2 b
and another one to keep the relations:
pk id interest_id
1 1 1
2 1 2
which this id is the id of the records in your main table.
With having this, you can easily use:
select count(*) from THIRD_TABLE where id = YOUR_ID
You can do this.
$place = array();
$interests = array();
foreach($rows as $row){
if (!isset($place[$row["place"]])){
$place[$row["place"]] = 0;
}
$place[$row["place"]]++;
$ints = explode(",", $row["interests"]);
foreach($ints as $int){
if (!isset($interests[$int])){
$interests[$int] = 0;
}
$interests[$int]++;
}
}
This will give you the two arrays keyed off of the relevant field with the value being the count. If this is going to be a common action in your application it would make more sense to normalize your data as suggested by AliBZ.
This is for the first result you need
SELECT place,COUNT(interest)
FROM `testtab`
GROUP by place
ORDER BY COUNT(interest) desc
can do this :
$inst_row = '';
foreach($rows as $row){
$inst_row .= $row['interests'];
}
$inst_values = explode(',', $inst_row);
$inst_count = array_count_values($inst_values);
// $inst_count will return you count as you want ,print_r it and format it accordingly

Categories