Pull smallest value - php

I know mysql has the MIN() function pulls out the smallest value located in a specific column.
I was wondering is there a way to pull out the smallest value for each corresponding id and exclude the values that equal 0?
For example, the 2 ids have multiple prices that were entered. I need to exclude '0', and then pull out the min for 1, and then the same for 2, etc etc.
id price
=============
1 0
1 33.0
1 21.7
2 0
2 99.22

Should be something like
select id, min(price) from t where price > 0 group by id;

select id, min(price)
from table
where price > 0
group by id

Related

Incrementing random cell in SQL with shared value

I want to select the lowest value in the 'n' sql column and increment it by 1. If the lowest value is present in multible rows, then I want to choose among those rows at random. For instance, in the example table below where the lowest number is 0 I want to randomly choose between the rows where ID = 1, 2, or 3.
ID
n
1
0
2
0
3
0
4
1
5
2
The code below will increment all three rows where n = 0. How do I randomly select just 1? I use Adminer as database.
$sql = "UPDATE studycondition SET n=n +1 WHERE n=(SELECT MIN(n) FROM studycondition)";
use
"UPDATE studycondition SET n=n +1 WHERE n=(SELECT MIN(n) FROM studycondition) limit 1"
Add limit in your inner query and update by id
UPDATE studycondition SET n = n + 1
WHERE id=(SELECT id FROM studycondition order by n asc limit 1)

MySql query to get non sold products from inventory table

I have 2 tables in my project. One is 'Products' another is 'Inventory Movement'.
'Products' table is just a master table with all our products loaded. It has only 2 fields
id - Auto increment field for product id
product_name - VarChar 255 unique column for product name
'Inventory Movement' table looks like below
id - Auto increment field
movement_type - Enum field (IN, OUT)
product - id from product table
quantity - No of items moving
movement_time - timestamp of action
Sample Data of movement table...
id movement_type product Quantity movement_time
1 IN 1001 10 2018-02-01 12:35:33
2 IN 1002 15 2018-02-01 13:33:33
3 OUT 1001 5 2018-03-01 11:00:33
now i have to take a report which list all products with the difference in time between its last 'OUT' and last 'IN' type records.
for a single product i wrote query like this...
1) Getting the last 'OUT' record;
select movement_time from inventory_movement where product = '1001' and movement_type='OUT' order by movement_time desc limit 1
2) Getting the last 'IN' record;
select movement_time from inventory_movement where product = '1001' and movement_type='IN' order by movement_time desc limit 1
3) Finding the diff between 2 timestamps.
this is how i know the unsold duration of the product with its id.
i know this is ineffective way... is there any way i can do this in single query ?
Is there anyway i get the list of products with this timestamp difference along with that ?
i.e.. the following is the expected output...
Product ---- Time Difference between last Out and last In
1001 ---- 40 days
1002 ---- 45 days
1004 ---- 12 days
Is it possible with single query ?
Seems that a DATEDIFF between a conditional MIN and MAX should do.
SELECT product,
DATEDIFF(MAX(case when movement_type='OUT' then movement_time end), MIN(case when movement_type='IN' then movement_time end)) AS InOutDayDiff
from inventory_movement
GROUP BY product
ORDER BY product
You can test it here

MySql get row if id is in sequence

We require to get row if product_id is in sequence.
Table (product)
product_id name
1 Parle
2 Coconut
3 Pizza
4 Colgate
5 Ice Cream
6 Nuts
8 Britania
9 Pepsi
Require Output
product_id name
1 Parle
2 Coconut
3 Pizza
4 Colgate
5 Ice Cream
6 Nuts
product_id - 8 and 9 not getting because it is not in sequence.
My Try
select distinct t1.*, t1.product_id, (select GROUP_CONCAT(t2.product_id) from product as t2) as p_id
from product t1
having FIND_IN_SET(t1.product_id+1, p_id)
Output
product_id name
1 Parle
2 Coconut
3 Pizza
4 Colgate
5 Ice Cream
In this try i am not getting product_id - 6 row.
Note : I want MySql query not in PHP.
Thank You !
One way i can think of is to user user defined variable to get the rank of row and then calculate the difference of product id and rank and select only those rows where difference = 0
select *
from(
select f.*,#row:= #row + 1 rank,
product_id - #row as diff
from product f,
(select #row:= 0) t
order by product_id
) t1
where diff = 0
Demo
Or if you want to pick the least sequence no. automatically you can write it as
select *
from(
select f.*,#row:= #row + 1 rank,
product_id - #row as diff
from product f,
(select #row:= (select min(product_id) from product_sale_flag) a) t
order by product_id
) t1
where diff = -1
Demo
Explanation
First query assign's minimum value of product_id to variable #row,then it assigns a rank to each row ordered by product_id in ascending order, once rank is assigned for every row then it calculates the difference between the original value of product_id and lastly using the resultant difference it checks where difference is 0 get those rows because they follow the sequence. Hope this makes sense

mysql second priority where clause

So for example I have a table users, with a column 'count' and a column 'uid' which is the primary key.
uid | count
1 | 20
2 | 20
3 | 20
4 | 20
4 | 18
I want to select exactly one row which has count less than or equal to the present row. For example, I have the row where uid = 2.
Now I want to select a column which has count less than or equal to the present count value which is "20". and I want to select exactly one row which is closest to it.
Now I will have the choice to select either the row which has uid = 3 or uid = 4. In such case, I will want to select the column with the lowest uid value such that it is greater than the present uid value which is 2. Therefore I will want uid = 3 as my result.
How to put this in a mysql query ?
So something like this?
SELECT * FROM users
WHERE count <= 20
ORDER BY count DESC, uid ASC
LIMIT 1
That'll sort the results so that everything above 20 is discarded, and you get the rest in decreasing count order, with lower user ids taking priority if there are multiples of the same count. The LIMIT 1 restricts the query to return only one row.
If you want to make the comparison to an existing row, your easiest bet is to do this:
SELECT * FROM users
WHERE count <= 20
AND uid != 2
ORDER BY count DESC, uid ASC
LIMIT 1
SELECT * FROM users
WHERE count <= 20
AND uid IN (3,4)
ORDER BY uid ASC,count DESC
LIMIT 1

how to build a dynamic runtime query in mysql php?

I do not know how to classify this question. Vaguely, its about using calculated value in the WHERE clause of a mysql query performed using a php script.
Here's the scenario -
I've a mysql table with structure like this: table_id[int], item_id[int], item_rating[int]
Now the item_rating column can have either a "1" or a "0" value in it. The table_id column is set to auto_increment and the item_id column can have duplicate values also.
So a typical table will look like below -
table_id item_id item_rating
1 item1 1
2 item5 0
3 item1 1
4 item1 1
5 item5 1
6 item1 0
What i intend to do i for each item_id, i count the number of item_rating = 1 and item_rating = 0 and then take the difference of item_rating values to get the final rating for that item (final_item_rating = item_rating(with value=1) - item_rating(with value=0) ).
Now the issue:
I have a php script that takes values from these tables, and then displays the item details ordered on the "final_item_rating" value - something like:
select * from table_name order by final_item_rating desc
only problem is, since this final_item_rating is not a column in itself, and is actually based on run time value of the query, how do i build a query?
hope i have the question clear :)
This query may help you:
SELECT sum(item_rating) AS SumRatings
FROM table_name
WHERE item_rating=1
GROUP BY item_id
ORDER BY SumRatings;
This query would sum the ratings, and order the result with the highest rating on top:
select item_id
, sum(case when item_rating = 1 then 1 else -1 end) as rating
from YourTable
group by
item_id
order by
sum(case when item_rating = 1 then 1 else -1 end) desc

Categories