I have 2 table name table 'hasil' and table 'kat_soal' to join and give rank on each 'KatID' field on 'hasil' table..
here is my hasil table :
HasilID KatID UserID JBenar JSalah Nilai
15 1 1000 2 1 66.66666666666666
16 3 1000 2 0 100
17 1 1001 1 2 33.33333333333333
18 3 1001 1 1 50
19 1 1002 3 0 90
20 3 1002 2 0 80
and there is my kat_soal table
KatID Kategori Lama
1 IPA 30
2 IPS 30
3 Matematika 30
4 Bahasa Indonesia 20
5 Bahasa Inggris 20
this my query generate rank:
SELECT a.KatID,a.UserID,b.Kategori,c.Nama,a.JBenar,a.JSalah,ROUND(a.Nilai,2) as Nilai,
FIND_IN_SET( a.Nilai, l.list) AS rank
from hasil a
JOIN kat_soal b
ON a.KatID = b.KatID
JOIN datauser c
ON a.UserID=c.UserID
CROSS JOIN
(SELECT GROUP_CONCAT( a2.Nilai ORDER BY a2.Nilai DESC ) as list
FROM hasil a2) l
WHERE a.KatID='1'
ORDER BY a.Nilai DESC;
my result
//FOR KatID=1
KatID UserID Kategori Nama JBenar JSalah Nilai rank
1 1002 IPA ratam 3 0 90.00 2
1 1000 IPA Tarsan 2 1 66.67 4
1 1001 IPA wisnu 1 2 33.33 6
//FOR KatID=3
3 1000 Matematika Tarsan 2 0 100.00 1
3 1002 Matematika ratam 2 0 80.00 3
3 1001 Matematika wisnu 1 1 50.00 5
My Expected Result
//FOR KatID=1
KatID UserID Kategori Nama JBenar JSalah Nilai rank
1 1002 IPA ratam 3 0 90.00 1
1 1000 IPA Tarsan 2 1 66.67 2
1 1001 IPA wisnu 1 2 33.33 3
//FOR KatID=3
3 1000 Matematika Tarsan 2 0 100.00 1
3 1002 Matematika ratam 2 0 80.00 2
3 1001 Matematika wisnu 1 1 50.00 3
anyone can help me ?
Good example to solve the issue is by looking at: http://www.fromdual.com/ranking-mysql-results .
You are making this a bit complicated: First You take the value, making the value a string, then "finding position in string".
From the example it should be completely ok if it is done as (untested):
SET #rank=0;
SELECT a.KatID,a.UserID,b.Kategori,c.Nama,a.JBenar,a.JSalah,ROUND(a.Nilai,2) as Nilai,
#rank:=#rank+1 AS rank
from hasil a
JOIN kat_soal b
ON a.KatID = b.KatID
JOIN datauser c
ON a.UserID=c.UserID
WHERE a.KatID='1'
ORDER BY rank;
EDIT: Changed ordering - You are expecting to by ordered by rank in the final.
Below is the script without using table datauser for any1 to test:
SET #rank=0;
SELECT a.KatID,a.UserID,b.Kategori,a.JBenar,a.JSalah,ROUND(a.Nilai,2) as Nilai,
#rank:=#rank+1 AS rank
from hasil a
JOIN kat_soal b
ON a.KatID = b.KatID
WHERE a.KatID='1'
ORDER BY rank;
Related
What I'm trying to do is to select a specific amount of tickets (max 2) and every person that has the sum of the number of tickets less of 3 and the valid field has to be != 'e'
I have this table:
ID
id_person
nr_tickets
valid
1
220
1
s
2
220
1
s
3
330
2
s
4
330
1
e
5
331
1
s
6
220
2
s
7
441
1
s
8
442
2
s
9
443
1
s
10
444
1
s
11
445
2
s
Here is what I did:
SELECT m.id, m.id_person, m.nr_tickets, m.valid
FROM table m
JOIN table m1 ON m1.id <= m.id
WHERE m.nr_tickets > 0
GROUP BY m.id
HAVING SUM(case when m.valid != 'e' then m1.nr_tickets end) <= 10
This query gives me
ID
id_person
nr_tickets
valid
1
220
1
s
2
220
1
s
3
330
2
s
5
331
1
s
6
220
2
s
7
441
1
s
8
442
2
s
As you can see the query it's almost right, the thing is that the person 220 in the results has the sum of the tickets is greater than 2.
What I'm trying to achieve is to bypass the ID 6, and to have instead the ID 9
select `id`,`id_person`, sum(`nr_tickets`) as `nr_tickets`, `valid`
from `test`
group by `id_person`
having sum(`nr_tickets`) < 3 and `valid`!="e"
Output:
id id_person nr_tickets valid
5 331 1 s
7 441 1 s
8 442 2 s
9 443 1 s
10 444 1 s
11 445 2 s
I have a user table like this
userId
username
balance
parentId
parentInfo
1
john
1000
0
0,
2
roy
2000
1
1,0,
3
James
2000
1
1,0,
4
Allen
5000
2
2,1,0,
5
Nell
4000
2
2,1,0,
6
Andy
1500
5
5,2,1,0,
I want to list all the users and sum of the balance for all their downline
like this
userId
username
balance
parentId
downlineBalance
1
john
1000
0
14500
2
roy
2000
1
10500
3
James
2000
1
0
4
Allen
5000
2
0
5
Nell
4000
2
1500
6
Andy
1500
5
0
WITH RECURSIVE
cte AS ( SELECT *, parentId upperId
FROM test
UNION ALL
SELECT cte.userId, cte.username, cte.balance, cte.parentId, test.parentId
FROM test
JOIN cte ON test.userId = cte.upperId
)
SELECT test.*, COALESCE(SUM(cte.balance), 0) downlineBalance
FROM test
LEFT JOIN cte ON test.userId = cte.upperId
GROUP BY test.userId
https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=506baa4e100d2eb76de4321343c9ba3d
I have a table1 for example:
orderID userId orderName orderTime...
1 11
2. 12
3. 11
4. 14
5. 11
6. 13
7. 11
8. 15
9. 16
10. 11
... ...
I have another table table2:
table2ID orderID item price ....
101 1 Apple 1.99
102 1 Banana 2.99
103 1 Grapes 0.99
104 4 pizza 6.99
105 4 drink 0.99
105. 3 chicken 1.99
106. 3 apple 1.99
I have tried this :
SELECT a.*, b.* FROM `table1` a
RIGHT JOIN table2 b on a.orderID = b.orderID
WHERE a.userID = 11 order by a.`orderTime` DESC LIMIT 25;
I want to get upto 10 unique orderIDs from table 1 of user 11 and all the details of that 10 ids from table 2. If I do LIMIT 25 then I don't get all the information.
I want my output as:
orderID userId orderName orderTime... table2ID orderID item price
1 11 101 1 Apple 1.99
1 11 102 1 Banana 2.99
1 11 103 1 Grapes 0.99
3 11 105 3 chicken 1.99
3 11 106 3 apple 1.99
SELECT a.*, b.*
FROM ( SELECT *
FROM a
WHERE a.userID = 11
LIMIT 10) as a
JOIN b
ON a.orderID = b.orderID
I have a data set:
sid name sub marks subid
11 kittu eng 55 1
11 kittu math 0 2
11 kittu sci 0 3
12 bunnu eng 0 1
12 bannu math 44 2
12 bannu sci 0 3
13 siva eng 0 1
13 siva math 0 2
13 siva sci 88 3
and I want to get output like this (which have consecutive zero marks):
11 kittu
13 siva
SELECT a row from T WHERE exists a row another with same sid and a lower subid sequentially and both rows have zero marks.
Then Do a DISTINCT just in case there are more than qualifying condition so you don't get duplicates.
SELECT DISTINCT sid,name
FROM t
WHERE EXISTS (SELECT 1 FROM T T2
WHERE T2.marks = 0
AND t.marks = 0
AND T2.sid = T.sid
AND T2.subid = t.subid + 1)
sqlfiddle
I'll try to explain it as simple as possible:
First some database structure with dummy data.
Structure
tb_spec_fk
feature value
-----------------
1 1
1 2
1 3
1 4
1 5
2 2
2 3
3 1
3 4
4 2
4 3
4 4
5 1
5 3
5 5
6 3
6 5
tb_spec_feature
feature_id filter
------------------
1 2
2 2
3 2
4 2
5 1
6 0
tb_spec_value
value_id name
----------------
1 10
2 20
3 30
4 40
5 50
Now, what I want is the follow result
Result
feature_id min_value max_value
---------------------------------
1 10 50
2 20 30
3 10 40
4 20 40
But how?
Logic
Get from the tb_spec_feature where "filter" equals 2 the highest and lowest values which are present in the tb_spec_value table and connected together trough the tb_spec_fk table.
My attemps
A lot! But I'll spare you :)
SELECT
f.feature_id AS feature_id,
MAX(value.name) AS max_value,
MIN(value.name) AS min_value
FROM tb_spec_feature AS f
JOIN tb_spec_fk AS fk ON f.feature_id=fk.feature
JOIN tb_spec_value AS value ON fk.value=value.id
WHERE f.filter=2
GROUP BY f.feature_id
The two JOIN statements "link" the a feature to a value. GROUP BY groups all rows with the same feature id, and then you can take the min or max or any other aggregate function on those columns.
Demo
Here is how you can do it
select
tsf.feature_id,
tsvl.name as Min_Value,
tsvr.name as Max_Value
from tb_spec_feature as tsf
inner join (select feature , MIN(value) MinV,MAX(value)MaxV from tb_spec_fk group by feature order by feature)as tsfkl on tsfkl.feature = tsf.feature_id
left join tb_spec_value as tsvl on tsvl.value_id = tsfkl.MinV
left join tb_spec_value as tsvr on tsvr.value_id = tsfkl.MaxV
where tsf.filter = 2
group by tsf.feature_id
Output
feature_id | Min_Value | Max_Value
---------------------------------
1 | 10 | 50
2 | 20 | 30
3 | 10 | 40
4 | 20 | 40
Fiddle Demo