mysql query for rating system - mysql

select
user_id,
#pos:=(#pos+1) as new_position,
(coins+total_item_costs) as wealth
from user_ledger
join users using (user_id),(select #pos:=0) p
ORDER BY wealth DESC
limit 10;
+---------+--------------+------------+
| user_id | new_position | wealth |
+---------+--------------+------------+
| 19 | 19 | 1112823871 |
| 11 | 11 | 13318047 |
| 8 | 8 | 7292407 |
| 6 | 6 | 6122746 |
| 27 | 27 | 5271889 |
| 23 | 23 | 5263050 |
| 9 | 9 | 5171734 |
| 3 | 3 | 5136092 |
| 15 | 15 | 5097488 |
| 4 | 4 | 5089487 |
+---------+--------------+------------+
10 rows in set (0.01 sec)
The new_position is incorrect..
What's wrong, guys? :)
ps. pls dont tell me to use temporary table

Should do the ORDER BY beforehand the position.
SELECT user_id,#pos:=(#pos+1) as new_position,wealth FROM (
select user_id,(coins+total_item_costs) as wealth from user_ledger join users
using (user_id) ORDER BY wealth DESC limit 10 ) a,(select #pos:=0) p

Related

MYSQL COUNT(column) returns multiple lines unexpectedly

I have two tables:
1. SELECT * FROM gas_trades_bids;
+----+---------+----------+--------+------------+------------+
| id | user_id | claim_id | amount | lots_value | timestmp |
+----+---------+----------+--------+------------+------------+
| 5 | 9 | 11 | 60 | NULL | 1571317861 |
| 6 | 9 | 11 | 100 | NULL | 1571656888 |
| 7 | 9 | 11 | 50 | NULL | 1571727353 |
| 8 | 9 | 11 | 50 | NULL | 1571918296 |
+----+---------+----------+--------+------------+------------+
4 rows in set (0.00 sec)
2. SELECT * FROM gas_trades_offers;
+----+---------+----------+--------+------------+----------+------------+
| id | user_id | claim_id | amount | lots_value | accepted | timestmp |
+----+---------+----------+--------+------------+----------+------------+
| 8 | 9 | 11 | 33 | 22 | NULL | 1571918576 |
| 9 | 9 | 11 | 33 | 22 | 1 | 1571918576 |
| 10 | 9 | 11 | 33 | 22 | 1 | 1571918576 |
+----+---------+----------+--------+------------+----------+------------+
3 rows in set (0.01 sec)
The goals are:
Count the amount of the rows where gas_trades_bids.claim_id = gas_trades_offers_claim_id and gas_trades_bids.claim_id = 11 and gas_trades_bids.user_id = 11
Get the sum of the column gas_trades_offers.lots_value values
To reach this I tried to run:
SELECT COUNT(bids.id) amount, SUM(offers.lots_value)
FROM gas_trades_offers offers, (SELECT * FROM gas_trades_bids) bids
WHERE bids.user_id = 9
AND bids.user_id = offers.user_id
But I've got the multiple rows:'
+--------+------------------------+
| amount | SUM(offers.lots_value) |
+--------+------------------------+
| 3 | 66 |
| 3 | 66 |
| 3 | 66 |
| 3 | 66 |
+--------+------------------------+
4 rows in set (0.01 sec)
What do I do in the wrong way?
I have expected to get only:
+--------+------------------------+
| amount | SUM(offers.lots_value) |
+--------+------------------------+
| 3 | 66 |
+--------|------------------------|
I don't need to use GROUP BY!
Is it exactly what you need? Hope that this query can work well.
SELECT COUNT(offers.id) amount,
SUM(offers.lots_value)
FROM gas_trades_offers offers
WHERE offers.user_id = 9 and offers.claim_id = 11
AND exists (SELECT id FROM gas_trades_bids bids WHERE bids.claim_id = offers.claim_id and bids.user_id = offers.user_id)
Try this:
SELECT COUNT(bids.id) amount,
SUM(offers.lots_value)
FROM gas_trades_offers offers
JOIN gas_trade_bids bids ON bids.user_id = offers.user_id
WHERE offers.user_id = 9;

Group condition in last data mysql

I have a data like this :
Table LOT
+-------+--------+
|Lot_id | Prod_id|
+-------+--------+
| LOT-1 | Prd-1 |
| LOT-1 | Prd-2 |
| LOT-1 | Prd-3 |
| LOT-2 | Prd-4 |
+-------+--------+
Table Process
+-------+--------+--------+------------+----------+
|proc_id|proc_cat|proc_seq|proc_prod_id|t_proc_qty|
+-------+--------+--------+------------+----------+
| 1 | Proc-A | 1 | Prd-1 | 100 |
| 2 | Proc-H | 2 | Prd-1 | 100 |
| 3 | Proc-D | 3 | Prd-1 | 100 |
| 4 | Proc-A | 1 | Prd-2 | 100 |
| 5 | Proc-H | 2 | Prd-2 | 100 |
| 6 | Proc-D | 3 | Prd-2 | 20 |
| 7 | Proc-Q | 4 | Prd-2 | 20 |
| 8 | Proc-A | 1 | Prd-3 | 100 |
| 9 | Proc-H | 2 | Prd-3 | 100 |
| 10 | Proc-D | 3 | Prd-3 | 50 |
| 11 | Proc-O | 1 | Prd-4 | 80 |
| 12 | Proc-F | 2 | Prd-4 | 80 |
| 13 | Proc-H | 3 | Prd-4 | 80 |
+-------+--------+--------+------------+----------+
And i want data like this if i want select just LOT=LOT-1.
table LOT joined to table Process and data is accumulated sum(t_proc_qty) from last proc_seq each proc_prod_id and group by proc_cat and order by proc_seq
+--------+--------+----------+
|proc_cat|proc_seq|t_proc_qty|
+--------+--------+----------+
| Proc-D | 3 | 150 |->accumulated from Prd-1 and prd-3 in last process is seq 3
| Proc-Q | 4 | 20 |->accumulated from Prd-2 in last process is seq 4
+--------+--------+----------+
What queries I use in MySQL ?
I stucked in query
SELECT proc_cat, proc_seq, SUM(t_proc_qty)
FROM Process
LEFT JOIN Lot ON proc_prod_id=Prod_id
WHERE Lot_id='LOT-1'
GROUP BY proc_prod_id
ORDER BY proc_seq DESC LIMIT 1
this schema for trial query SQLFiddle
From table Process you want the records with the highest proc_id per proc_prod_id:
select *
from process
where not exists
(
select *
from process later
where later.proc_prod_id = process.proc_prod_id
and later.proc_id > process.proc_id
);
From this data you want an aggregate per proc_cat and proc_sec. And you also want to consider only prod_id for 'LOT-1' in table LOT.
The complete query:
select proc_cat, proc_seq, sum(t_proc_qty)
from process
where proc_prod_id in (select prod_id from lot where lot_id = 'LOT-1')
and not exists
(
select *
from process later
where later.proc_prod_id = process.proc_prod_id
and later.proc_id > process.proc_id
)
group by proc_cat, proc_seq
order by proc_cat, proc_seq;
SQL fiddle: http://sqlfiddle.com/#!9/1fa3fd/5

I have a challenging MySQL SELECT query that involves stock and threshold bondary

I Have a MySQL DataBase which contains two tables linked with a foreign key:
MatPr(id, Designation, threshold_stock)
And
MvtStock_MatPr(id, Qte_Mvt, Qte_Tot,idMatPr)
What I want is to get the last Qte_tot, Designation,threshold_stock where threshold_stock>qte_tot
I tried this code and did not work:
SELECT MvtStock_MatPr.id,idMatPr, Nom, threshold_stock, Qte_Tot
FROM MvtStock_MatPr, MatPr
WHERE MatPr.id=MvtStock_MatPr.idMatPr AND threshold_stock>Qte_Tot
Here is Sample Data set:
mysql> SELECT MvtStock_MatPr.id,idMatPr, Designation, threshold_stock, Qte_Tot FROM MvtStock_MatPr, MatPr WHERE MatPr.id=MvtStock_MatPr.idMatPr AND threshold_stock>Qte_Tot ORDER
BY id,idMatPr;
| id | idMatPr | Dsignation| threshold_stock| Qte_Tot |
| 1 | 1 | bakra | 120 | 10 |
| 2 | 2 | zipper | 130 | 20 |
| 3 | 1 | bakra | 120 | 30 |
| 7 | 2 | zipper | 130 | 50 |
4 rows in set (0.00 sec)
mysql> SELECT * FROM MatPr;
| id | Designation| threshold_stock|
| 1 | bakra | 120 |
| 2 | zipper | 130 |
2 rows in set (0.00 sec)
mysql> SELECT * FROM MvtStock_MatPr;
| id | DateMvt | Qte_Mvt | Qte_Tot | idMatPr |
| 1 | 2016-01-01 | 10 | 10 | 1 |
| 2 | 2016-02-02 | 20 | 20 | 2 |
| 3 | 2016-03-03 | 20 | 30 | 1 |
| 4 | 2016-03-03 | 100 | 130 | 1 |
| 5 | 2016-03-03 | 50 | 180 | 1 |
| 6 | 2016-03-03 | 20 | 200 | 1 |
| 7 | 2016-03-05 | 30 | 50 | 2 |
7 rows in set (0.00 sec)
What I would like to get is:
| id | idMatPr | Dsignation| threshold_stock| Qte_Tot
| 3 | 1 | bakra | 120 | 30 |
| 7 | 2 | zipper | 130 | 50 |
+----+---------+--------+-------+---------+
Thanks for your contributions
Use the below query
Select m1.id,m1.idMatpr,m.threshold_stock,m.Qte_Tot
From MvtStock_Matpr m1 join Matpr m
On m1.idMatPr=m.id and m.threshold_stock>m1.Qte_Tot
I'm not sure that I completely follow what your problem is: is it selecting just one row from a result set? If so, does a subquery fix your problem?
SELECT *
FROM MatPr
WHERE ID = (
SELECT idMatPr
FROM MvtStock_MatPr, MatPr
WHERE MatPr.id = MvtStock_MatPr.idMatPr
AND threshold_stock > Qte_Tot
LIMIT 1
)
If you want to select just the rows from MatPr, does this work for you?
SELECT MatPr.*
FROM MvtStock_MatPr, MatPr
WHERE MatPr.id = MvtStock_MatPr.idMatPr
AND threshold_stock > Qte_Tot
http://sqlfiddle.com/#!9/d4ef50/2
Try this query:
select * from
( SELECT MvtStock_MatPr.id,idMatPr,Designation, threshold_stock, Qte_Tot
FROM MvtStock_MatPr join MatPr
on MatPr.id=MvtStock_MatPr.idMatPr
where threshold_stock>Qte_Tot
order by DateMvt desc
) T
group by T.idMatPr

Complex order by mysql

if I have a table like this
+----+----------------+
| id | id_alternativo |
+----+----------------+
| 15 | 18 |
+----+----------------+
| 16 | 0 |
+----+----------------+
| 17 | 0 |
+----+----------------+
| 18 | 0 |
+----+----------------+
How can I order records to show id 18 after id 15?
Looking at the MySQL documentation you can use multiple columns in your sort and use DESC/ASC per column.
http://dev.mysql.com/doc/refman/5.7/en/order-by-optimization.html
If I understand correctly what you mean your query will look as followed:
SELECT id, id_alternativo FROM table ORDER BY id_alternativo DESC, id DESC;
+------+----------------+
| id | id_alternativo |
+------+----------------+
| 15 | 18 |
| 18 | 0 |
| 17 | 0 |
| 16 | 0 |
+------+----------------+
One solution is to use a self join like this:
select t.*
from
yourtable t left join yourtable o
on t.id = o.id_alternativo
order by
coalesce(o.id, t.id), t.id
this will put all alternative ids after the main id (in this case 18 will follow 15).
Please see a fiddle here. Please note that this will work unless an alternative id has another alternative id (e.g. if 18 itself has another alternative id) but this cannot be solved purely with MySQL as it does not support recursive queries yet.
from what I understand just use order by id (18, 15) and any other id you need.
select id,id_alternativo
from table_name
order by case id when 15 Then 1
when 18 Then 2
when 16 Then 3
when 17 Then 4
else 5
end;
you can use order like this:
SELECT id
FROM mytab
ORDER BY IF(id=18,155,id*10);
sample
MariaDB []> select id from mytab;
+----+
| id |
+----+
| 1 |
| 2 |
| 3 |
| 4 |
| 9 |
| 10 |
| 11 |
| 12 |
| 13 |
| 14 |
| 15 |
| 16 |
| 17 |
| 18 |
| 19 |
+----+
15 rows in set (0.00 sec)
MariaDB []> SELECT id
-> FROM mytab
-> ORDER BY IF(id=18,155,id*10);
+----+
| id |
+----+
| 1 |
| 2 |
| 3 |
| 4 |
| 9 |
| 10 |
| 11 |
| 12 |
| 13 |
| 14 |
| 15 |
| 18 |
| 16 |
| 17 |
| 19 |
+----+
15 rows in set (0.00 sec)
MariaDB []>
Sorry, I used a simple example but my table is more complex. The id_alternativo can be recursive (id 18 could have an id_alternativo = 19) and so on and id_alternativo could not be the most high id on table so ORDER BY id_alternativo DESC, id DESC doesn't work. Here's a query from my table:
SELECT
a.id, a.compatibile, a.id_alternativo
FROM
ordini_righe AS a
WHERE
intestazione IN (398010) AND a.canc = 0
AND a.stato_ordine = 0
Here's the result
+-------+-------------+----------------+
| id | compatibile | id_alternativo |
+-------+-------------+----------------+
|828924 | 0 | 828931 |
+-------+-------------+----------------+
|828925 | 828932 | 0 |
+-------+-------------+----------------+
|828926 | 0 | 0 |
+-------+-------------+----------------+
|828927 | 0 | 0 |
+-------+-------------+----------------+
|828931 | 0 | 828933 |
+-------+-------------+----------------+
|828932 | 828932 | 0 |
+-------+-------------+----------------+
|828933 | 0 | 0 |
+-------+-------------+----------------+
I had to order compatibile desc and then order the other records by the relation beetween id_alternativo and id. So i solved using a new column like this
SELECT
a.id, a.compatibile, a.id_alternativo, IF(id_alternativo = 0, a.id, id_alternativo) ordine
FROM
ordini_righe AS a
JOIN
locazioni AS b ON a.locazione = b.id
JOIN
stati_righe AS c ON a.stato_ordine = c.id
WHERE
intestazione IN (398010) AND a.canc = 0
AND a.stato_ordine = 0
ORDER BY compatibile DESC, ordine, a.id ASC
And I got the desired result
+-------+-------------+----------------+--------+
| id | compatibile | id_alternativo | ordine |
+-------+-------------+----------------+--------+
|828925 | 828932 | 828931 | 828925 |
+-------+-------------+----------------+--------+
|828932 | 828932 | 0 | 828932 |
+-------+-------------+----------------+--------+
|828926 | 0 | 0 | 828926 |
+-------+-------------+----------------+--------+
|828927 | 0 | 0 | 828927 |
+-------+-------------+----------------+--------+
|828924 | 0 | 828931 | 828931 |
+-------+-------------+----------------+--------+
|828931 | 0 | 828933 | 828933 |
+-------+-------------+----------------+--------+
|828933 | 0 | 0 | 828933 |
+-------+-------------+----------------+--------+

MySQL combine results from UNION of same-scheme tables

There are two tables with the same structure: 'imsc_storage_users' & 'imsc_storage_users_archive'.
My current SELECT/UNION:
SELECT `cli`,`ts`,`questions`, `answers`,`correct`,`last`,`minutes`
FROM `imsc_storage_users`
UNION DISTINCT
SELECT `cli`,`ts`,`questions`, `answers`,`correct`,`last`,`minutes`
FROM `imsc_storage_users_archive`
ORDER BY `correct` DESC,`minutes` ASC
I'm getting these results:
+--------------+---------------------+-----------+---------+---------+------+---------+
| cli | ts | questions | answers | correct | last | minutes |
+--------------+---------------------+-----------+---------+---------+------+---------+
| 111111111111 | 2011-12-22 11:13:57 | 30 | 29 | 14 | 30 | 1305.47 |
| 222222222222 | 2011-12-15 13:39:16 | 26 | 24 | 13 | 24 | 15.67 |
| 333333333333 | 2011-12-15 13:39:39 | 26 | 25 | 11 | 25 | 15.18 |
| 444444444444 | 2011-12-15 13:39:39 | 25 | 21 | 11 | 25 | 280.53 |
| 111111111111 | 2011-12-22 11:13:57 | 25 | 21 | 10 | 25 | 373.87 |
| 555555555555 | 2011-12-19 15:46:15 | 11 | 10 | 5 | 10 | 3.8 |
| 666666666666 | 2011-12-15 13:39:16 | 14 | 10 | 4 | 10 | 321.64 |
| 777777777777 | 2011-12-19 08:34:36 | 15 | 11 | 4 | 13 | 474.66 |
Notice that '111111111111' appears twice?
I want it to be combined, so in the results set I get one row of '111111111111' which combines/sums all fields; 'questions' =>> 55.... etc'.
What would be the correct SQL?
Performance are NOT of an issue here.
Thank you!
SELECT `cli`,max(`ts`) AS ts, sum(`questions`) as questions, sum(`answers`) as answers,sum(`correct`) as correct,sum(`last`) as last,sum(`minutes`) as minutes
FROM (
SELECT `cli`,`ts`,`questions`, `answers`,`correct`,`last`,`minutes`
FROM `imsc_storage_users`
UNION ALL
SELECT `cli`,`ts`,`questions`, `answers`,`correct`,`last`,`minutes`
FROM `imsc_storage_users_archive`
) AS baseview
GROUP BY cli
ORDER BY `correct` DESC,`minutes` ASC
Try:
SELECT `cli`,
`ts`,
sum(`questions`),
sum(`answers`),
sum(`correct`),
sum(`last`),
sum(`minutes`)
FROM (SELECT `cli`,`ts`,`questions`, `answers`,`correct`,`last`,`minutes`
FROM `imsc_storage_users`
UNION ALL
SELECT `cli`,`ts`,`questions`, `answers`,`correct`,`last`,`minutes`
FROM `imsc_storage_users_archive`) V
group by `cli`, `ts`
ORDER BY 5 DESC, 7 ASC