Need to get MAX selling price in last 4 transaction - mysql

I have a table named sellingDetails.
Table Data is as follows
+--------+----------------+
| id | sellingPrice |
+--------+----------------+
| 1 | 35000 |
| 2 | 40000 |
| 3 | 30000 |
| 4 | 25000 |
| 5 | 35000 |
| 6 | 33000 |
| 7 | 25000 |
+--------+----------------+
When I query
SELECT id, sellingPrice
FROM sellingDetails
ORDER BY id DESC limit 0, 4
The above query outputs:
+--------+----------------+
| id | sellingPrice |
+--------+----------------+
| 7 | 25000 |
| 6 | 33000 |
| 5 | 35000 |
| 4 | 25000 |
+--------+----------------+
Out of the above result how I can get the MAX result i.e. 35000.
I tried using MAX(sellingprice) but it didn't work.
this question is very near to mine but it has joins whereas mine is a single table
DB Fiddle
If I use the below query
SELECT MAX(sellingprice) FROM sellingdetails
ORDER BY id DESC
LIMIT 0, 4;
I get output as 40000 which is not intended.

You can use your existing query as a Derived Table and then determine the maximum value from it.
SELECT MAX(dt.sellingPrice)
FROM
(
SELECT sellingPrice
FROM sellingDetails
ORDER BY id DESC limit 0, 4
) dt
Result
| MAX(dt.sellingPrice) |
| -------------------- |
| 35000 |
View on DB Fiddle

Related

GROUP and ORDER Mysql get diffrent data in column

this is all data from current table
SELECT
id,harga,kode_tahun_ajaran
FROM
tblharga
+----+---------+-------------------+
| id | harga | kode_tahun_ajaran |
+----+---------+-------------------+
| 1 | 400000 | THN2018/2019 |
| 2 | 50000 | THN2018/2019 |
| 3 | 1000000 | THN2018/2019 |
| 4 | 900000 | THN2018/2019 |
| 5 | 500000 | THN2017/2018 |
| 6 | 600000 | THN2018/2019 |
+----+---------+-------------------+
and i run this code to get the last harga with grouping the kode_tahun_ajaran
SELECT
id,harga,kode_tahun_ajaran
FROM
tblharga
GROUP BY
kode_tahun_ajaran
ORDER BY id DESC
+----+--------+-------------------+
| id | harga | kode_tahun_ajaran |
+----+--------+-------------------+
| 5 | 500000 | THN2017/2018 |
| 1 | 400000 | THN2018/2019 |
+----+--------+-------------------+
the harga column should take the last data which is 600000 because of the order by code.
how can I retrieve the latest data by grouping it another way?
thanks in advance.
You can try below
SELECT
id,harga,kode_tahun_ajaran
FROM
tblharga where id in (select max(id) from tblharga group by kode_tahun_ajaran)
select id,S.kode_tahun_ajaran,harga
from tblharga S inner join
( select kode_tahun_ajaran,max(id) maxid from tblharga group by kode_tahun_ajaran) T
where T.kode_tahun_ajaran=S.kode_tahun_ajaran and maxid=id;

SQL query that randoms the id from all posible ids in table and outputs the rows containing that id

I want a query that selects all rows that have the UploadedbyUserID = Rand() (selects random id from possible UploadbyUserID in this case 4, 3 and 22 and only those 3 not 2 nor 5)
And if the rand gives 4 it outputs this:
+------+------+------------+--------------------+
| id | name | date | UploadedbyUserID |
+------+------+------------+--------------------+
| 1 | 2222 | Testing | 4 |
| 2 | Jack | description| 4 |
| 6 | Zara | 2007-02-06 | 4 |
+------+------+------------+--------------------+
This is the whole table
+------+------+------------+--------------------+
| id | name | date | UploadedbyUserID |
+------+------+------------+--------------------+
| 1 | 2222 | Testing | 4 |
| 2 | Jack | description| 4 |
| 3 | ffdsd| 2007-05-06 | 4 |
| 4 | dsm | 2007-05-27 | 3 |
| 5 | dddd | 2007-04-06 | 3 |
| 6 | Zara | 2007-02-06 | 4 |
| 7 | John | 2007-01-24 | 22 |
+------+------+------------+--------------------+
and if it randomizes 3 it outputs this
+------+------+------------+--------------------+
| id | name | date | UploadedbyUserID |
+------+------+------------+--------------------+
| 4 | dsm | 2007-05-27 | 3 |
| 5 | dddd | 2007-04-06 | 3 |
+------+------+------------+--------------------+
Ask if you need more information
Hmmm. This is one way:
select t.*
from (select uploadedbyuserid
from t
order by rand()
limit 1
) u join
t
using (uploadedbyuserid);
First, let me say that this is weighted by the number of times that a user has uploaded something. So, user "4" would appear a bit more often than "3", in your example. If this is an issue:
select t.*
from (select uploadedbyuserid
from (select distinct uploadedbyuserid from t) t
order by rand()
limit 1
) u join
t
using (uploadedbyuserid);
The next observation is that this can be compute intensive. If you have lots of rows, there are various ways to speed these up. For instance, one simple method would be to get about 1 out of 10000 rows:
select t.*
from (select uploadedbyuserid
from (select distinct uploadedbyuserid
from t
) t
where rand() < 0.001
order by rand()
limit 1
) u join
t
using (uploadedbyuserid);

MySQL query to select only entries where value = X and value <> Y

Raw MySQL queries are absolutely not my forte, so I'm struggling with this a bit, but: with a straightforward table layout like this:
+----+-----------+----------+---------------------+
| id | status_id | order_id | created_at |
+----+-----------+----------+---------------------+
| 1 | 1 | 1 | 2016-03-21 20:40:39 |
| 2 | 3 | 1 | 2016-03-21 20:40:45 |
| 3 | 5 | 1 | 2016-03-21 20:47:14 |
| 4 | 1 | 2 | 2016-03-25 12:14:44 |
| 6 | 3 | 2 | 2016-03-25 12:16:12 |
| 7 | 5 | 2 | 2016-03-25 12:47:43 |
| 8 | 1 | 3 | 2016-03-26 17:25:12 |
| 9 | 3 | 3 | 2016-03-26 17:25:48 |
+----+-----------+----------+---------------------+
I want to select only the order_id rows where the status_id equals 3, but not where that same order_id has a status_id of 5. As a result, my query should only return order ID 3, but my current query returns all 3 order IDs in the results:
$statusQueryString = 'SELECT DISTINCT order_id
FROM shop_order_status_log_records
WHERE status_id = 3 AND status_id <> 5 ORDER BY created_at';
Where am I going wrong with my query?
Use post aggregate filtering when you need 2 or more conditions per group.A simple rule WHERE filters rows HAVING filters groups
SELECT order_id FROM shop_order_status_log_records
GROUP BY order_id
HAVING SUM(status_id = 3)>0
AND SUM(status_id = 5)=0

Mysql query to find sum of fields with same column value

I have a table like this
id | invent_id | order
1 | 95948214 | 70
2 | 46018572 | 30
3 | 46018572 | 20
4 | 46018572 | 50
5 | 36025764 | 60
6 | 36025764 | 70
7 | 95948214 | 80
8 | 95948214 | 90
I want get the sum of order qty with same invent id
That is the want the result like this
| invent_id | order
| 95948214 | 240
| 46018572 | 100
| 36025764 | 130
how can we write the mysql query
Make use of Aggregate function SUM and grouped them according to invent_id.
SELECT invent_id, SUM(`order`) `Order`
FROM tableName
GROUP BY invent_ID
GROUP BY clause
SQLFiddle Demo

Top 'n' results for each keyword

I have a query to get the top 'n' users who commented on a specific keyword,
SELECT `user` , COUNT( * ) AS magnitude
FROM `results`
WHERE `keyword` = "economy"
GROUP BY `user`
ORDER BY magnitude DESC
LIMIT 5
I have approx 6000 keywords, and would like to run this query to get me the top 'n' users for each and every keyword we have data for. Assistance appreciated.
Since you haven't given the schema for results, I'll assume it's this or very similar (maybe extra columns):
create table results (
id int primary key,
user int,
foreign key (user) references <some_other_table>(id),
keyword varchar(<30>)
);
Step 1: aggregate by keyword/user as in your example query, but for all keywords:
create view user_keyword as (
select
keyword,
user,
count(*) as magnitude
from results
group by keyword, user
);
Step 2: rank each user within each keyword group (note the use of the subquery to rank the rows):
create view keyword_user_ranked as (
select
keyword,
user,
magnitude,
(select count(*)
from user_keyword
where l.keyword = keyword and magnitude >= l.magnitude
) as rank
from
user_keyword l
);
Step 3: select only the rows where the rank is less than some number:
select *
from keyword_user_ranked
where rank <= 3;
Example:
Base data used:
mysql> select * from results;
+----+------+---------+
| id | user | keyword |
+----+------+---------+
| 1 | 1 | mysql |
| 2 | 1 | mysql |
| 3 | 2 | mysql |
| 4 | 1 | query |
| 5 | 2 | query |
| 6 | 2 | query |
| 7 | 2 | query |
| 8 | 1 | table |
| 9 | 2 | table |
| 10 | 1 | table |
| 11 | 3 | table |
| 12 | 3 | mysql |
| 13 | 3 | query |
| 14 | 2 | mysql |
| 15 | 1 | mysql |
| 16 | 1 | mysql |
| 17 | 3 | query |
| 18 | 4 | mysql |
| 19 | 4 | mysql |
| 20 | 5 | mysql |
+----+------+---------+
Grouped by keyword and user:
mysql> select * from user_keyword order by keyword, magnitude desc;
+---------+------+-----------+
| keyword | user | magnitude |
+---------+------+-----------+
| mysql | 1 | 4 |
| mysql | 2 | 2 |
| mysql | 4 | 2 |
| mysql | 3 | 1 |
| mysql | 5 | 1 |
| query | 2 | 3 |
| query | 3 | 2 |
| query | 1 | 1 |
| table | 1 | 2 |
| table | 2 | 1 |
| table | 3 | 1 |
+---------+------+-----------+
Users ranked within keywords:
mysql> select * from keyword_user_ranked order by keyword, rank asc;
+---------+------+-----------+------+
| keyword | user | magnitude | rank |
+---------+------+-----------+------+
| mysql | 1 | 4 | 1 |
| mysql | 2 | 2 | 3 |
| mysql | 4 | 2 | 3 |
| mysql | 3 | 1 | 5 |
| mysql | 5 | 1 | 5 |
| query | 2 | 3 | 1 |
| query | 3 | 2 | 2 |
| query | 1 | 1 | 3 |
| table | 1 | 2 | 1 |
| table | 3 | 1 | 3 |
| table | 2 | 1 | 3 |
+---------+------+-----------+------+
Only top 2 from each keyword:
mysql> select * from keyword_user_ranked where rank <= 2 order by keyword, rank asc;
+---------+------+-----------+------+
| keyword | user | magnitude | rank |
+---------+------+-----------+------+
| mysql | 1 | 4 | 1 |
| query | 2 | 3 | 1 |
| query | 3 | 2 | 2 |
| table | 1 | 2 | 1 |
+---------+------+-----------+------+
Note that when there are ties -- see users 2 and 4 for keyword "mysql" in the examples -- all parties in the tie get the "last" rank, i.e. if the 2nd and 3rd are tied, both are assigned rank 3.
Performance: adding an index to the keyword and user columns will help. I have a table being queried in a similar way with 4000 and 1300 distinct values for the two columns (in a 600000-row table). You can add the index like this:
alter table results add index keyword_user (keyword, user);
In my case, query time dropped from about 6 seconds to about 2 seconds.
You can use a pattern like this (from Within-group quotas (Top N per group)):
SELECT tmp.ID, tmp.entrydate
FROM (
SELECT
ID, entrydate,
IF( #prev <> ID, #rownum := 1, #rownum := #rownum+1 ) AS rank,
#prev := ID
FROM test t
JOIN (SELECT #rownum := NULL, #prev := 0) AS r
ORDER BY t.ID
) AS tmp
WHERE tmp.rank <= 2
ORDER BY ID, entrydate;
+------+------------+
| ID | entrydate |
+------+------------+
| 1 | 2007-05-01 |
| 1 | 2007-05-02 |
| 2 | 2007-06-03 |
| 2 | 2007-06-04 |
| 3 | 2007-07-01 |
| 3 | 2007-07-02 |
+------+------------+