How to get a row position using eloquent - php

I have a leaderboard which shows the top people who have had the most sales.
It's simple. It just gets the top 25 and displays them
$user = \App\User::orderBy('sales', 'desc')
->take(25)
->get();
So that could end up with
+-------+-------------------+
| pos |user_id| sales |
----------------------------|
| 1 | 1 | 1,293 |
| 2 | 99 | 1,093 |
| 3 | 45 | 985 |
| 4 | 948 | 900 |
| 5 | 39 | 889 |
| 6 | 29 | 887 |
+---------------------------+
Now how can I get the position of the user who is viewing the leaderboard if they are not in the top 25?
If the user id 219 is at the position 935 I want to display something like this at the end
+-------+-------------------+
| pos |user_id| sales |
|---------------------------|
| 935 | 219 | 87 |
+---------------------------+
How is this possible to do efficiently without counting up to the user? (As there are thousands of users)

I suppose you have current user data. So, you don't have to query database to get current user id or sales. So, the main problem is to find count of users who have more sales than current.
So, you need a query like
SELECT COUNT(*) as pos FROM your_table WHERE sales > %current_user_sales%
Translate it to laravel query and add 1 when ouptutting.

Related

Fetch results in group based on the occurrence

Ok, I have a single MySQL table with the name 'car' and 3 columns.
+----+--------+------------+
| ID | car_id | engine |
+----+--------+------------+
| 1 | 123 | on |
| 2 | 123 | on |
| 3 | 123 | off |
| 4 | 123 | on |
| 5 | 123 | on |
| 6 | 123 | on |
| 7 | 123 | off |
| 8 | 123 | on |
| 9 | 123 | off |
+----+--------+------------+
Now I want to show the trips this car did. The trips would be determined based on car engine start and stop. For example from the above example we can see that user has made 3 trips as total(From on to off). Now What I want is that if there is a query which gives me only 3 results from on to off meaning if somehow the query groups the records by considering a starting point on and ending point off. Is it possible in mysql? or the other way around is doing it manually by fetching all the records and working in arrays?
At the moment I am fetching all the records and doing it manually by looping all the data and doing accordingly But this process is slow.
Can you try it ?
SELECT * from cars WHERE `engine` = 'off' AND id IN(SELECT id+1 FROM `cars` WHERE `engine` = 'on')

MySQL query to return unique values in one column and sorted by id to get a PHP array

I have the following simplified table: (Note we skipped 2nd exam in the exam_id)
+----+---------+-------+
| id | exam_id | score |
+----+---------+-------+
| 1 | 1 | 15 |
| 2 | 1 | 20 |
| 3 | 1 | 68 |
| 4 | 3 | 92 |
| 5 | 3 | 10 |
+----+---------+-------+
I want to write an $sql and some php (I'm using Wordpress, and can use $wpdb) to be able to get the following:
$exam[3]=10
$exam[1]=68
Not that when there are multiple exams, we take the score entry which corresponds to the largest id
And $exam[2] is empty. In words, I'd like to save the last ever exam that the user attempted and show their score.
I've tried using Group By and
Try this
SELECT
*
FROM exams
WHERE exams.id IN (
SELECT
MAX(id)
FROM exams
GROUP BY exam_id
);

Get last inserts from multiple tables

i am trying to build something like an order management tool for a car garage.
The main function of the tool is to manage repair orders and inspection orders as well
Therefore i have created this following three tables.
In the first one you can see the cars and the state of the repair and inspection.
The second one shows the information about the single repair orders the relation between the first and this is 1:n.
The last one shows the automaticly created inspection orders for each car out of the first table. This is an 1:n relation as well.
So what i try to do is to show all the open repair and inspection orders for the cars in one table. But only the open ones.
I tried it with some where statements but i got totaly confused.
My question is, how i can realise it?
+------+--------------------------+----------+------------+
| IDWZ | wz_name | wz_stand | wz_vistand |
+------+--------------------------+----------+------------+
| 1 | Querbr?cke vorn | 0 | 0 |
| 2 | Front Lateral Support | 0 | 1 |
| 3 | Rear Support | 1 | 1 |
| 4 | MID-X-Member Upper Shell | 1 | 1 |
| 5 | Front Lateral Support | 1 | 1 |
+------+--------------------------+----------+------------+
+---------+-----------------+--------------+
| IDWZTBL | rep_wzrepstatus | rep_wzfehler |
+---------+-----------------+--------------+
| 2 | 1 | REP 1 |
| 1 | 1 | REp2 |
| 1 | 1 | REp 3 MASS |
| 1 | 0 | 444 |
| 2 | 0 | |
+---------+-----------------+--------------+
+--------+-------------+
| VIWZID | vi_repstand |
+--------+-------------+
| 1 | 0 |
+--------+-------------+
Sry for that!
So the IDWZ is the foreign KEY in the second table(IDWZTBL) and in the third (VIWZID).
I tried it with
SELECT wz_name, wz_stand, wz_vistand, rep_wzrepstatus, vi_repstand FROM tbl_wz LEFT JOIN tbl_orders ON tbl_wz.IDWZ = tbl_orders.IDWZTBL LEFT JOIN tbl_vi ON tbl_wz.IDWZ = tbl_vi.VIWZID WHERE wz_stand='0' AND rep_wzrepstatus='0' ...
Only for the first table cars to the second one repair orders, that WHERE staement (WHERE wz_stand='0' AND rep_wzrepstatus='0') works fine.
But if i try to add the third table (VI) doing the same, i could fetch the result i wanna have.
What i wanna see in the Overview table is only the last open repair order and the last open inspection order.

MySQL Search Double with Currency Format

I have a PHP Based App that stores invoices entered by the user. Currently I have the invoice amount stored in a MySQL database tables as a double like so:
+------+--------------+--------------+----------------+----------------+-------------+-----------+---------------+-------------+-------------+-----------------+
| id | date_entered | invoice_date | invoice_number | invoice_amount | client_type | unique_id | supplier_type | supplier_id | category_id | childcare_hours |
+------+--------------+--------------+----------------+----------------+-------------+-----------+---------------+-------------+-------------+-----------------+
| 1 | 1411098397 | 1411048800 | 123 | 0.01 | 0 | 137 | 0 | 139 | 5 | NULL |
| 2 | 1412123404 | 1416920400 | 5093 | 130 | 0 | 168 | 0 | 19 | 18 | NULL |
| 3 | 1412125933 | 1412085600 | 000 | 79 | 0 | 151 | 0 | 177 | 8 | NULL |
| 4 | 1412645652 | 1412600400 | 000 | 60.8 | 0 | 104 | 0 | 179 | 9 | NULL |
| 5 | 1412647563 | 1409320800 | 804560 | 225.5 | 0 | 18 | 0 | 174 | 10 | NULL |
I am also using DataTables toorganise the data. I am using Server Side Processing to perform the data lookup to return as JSON.
The issue I am having is that the User is attempting to search by price eith by typing $123 or 123.50 This is not working as the SQL is being genrated like so: SELECT * FROM invoices WHERE invoice_amount LIKE "%$123%";
This is obviosuly failing due to the data being stored in the database as a double.
My Question is, is there a way to make the SQL (or Maybe PHP) search for the correct value no matter what the client types in?
I don't think there is any generic solution for the problem that you are facing but yeah you can remove the special characters like $ etc. from the beginning or end of the invoice amount to be placed in the query. Moreover I'll recommend that you should use functions as round in PHP as well as MySQL in the best possible fashion rather than using the LIKE statement. Using LIKE statement is absolutely incorrect in this situation.
You can try query without "$"
SELECT * FROM invoices WHERE invoice_amount LIKE "%123%";

MySQL Count to rows as one

I have a database as laid out below.
mysql> select * from wants where itemname='lamp' order by location;
+------+--------------------+-------------+----------+----------+----------+
| sess | username | room | image | item | priority |
+------+--------------------+-------------+----------+----------+----------+
| 33 | user1#aol.com | Family Room | DSC00649 | Lamp | 1 |
| 235 | user2#yahoo.com | Family Room | DSC00649 | Lamp | 2 |
| 60 | user3#homtmail.com | Foyer | DSC00527 | Lamp | 1 |
| 197 | user4#gmail.com | Foyer | DSC00527 | Lamp | 2 |
| 189 | user4#gmail.com | Living Room | DSC00827 | Lamp | 1 |
| 273 | user5#live.com | Living Room | DSC00827 | Lamp | 2 |
+------+--------------------+-------------+----------+----------+----------+
6 rows in set (0.00 sec)
What I am trying to do is get a count of each item per room.
When I run the query it should look like:
2 Family Room Lamp user1#aol.com user2#yahoo.com
2 Foyer Lamp user3#homtmail.com user4#gmail.com
2 Living Room Lamp user4#gmail.com user5#live.com
Current Query:
$result1 = mysql_query("SELECT username, location, image, itemname, COUNT( itemname ) x FROM wants GROUP BY itemname HAVING x >1 order by location ASC")
This will give the following output:
6 Family Room Lamp luser1#aol.com user2#yahoo.com user3#homtmail.com user4#gmail.com user4#gmail.com user5#live.com
I tried to use Concat to get the count of the first two rows but that did not help,
How can i break these out to get the rooms to read separately, when the Item name is the same?
You need to group by the room instead of the item. Also sounds like you're looking for group_concat to list the users:
select count(*),
room,
group_concat(username)
from wants
where item ='lamp'
group by room
SQL Fiddle Demo

Categories