MySql query to count the score of each user - mysql

The query needs to counts the total points for each user. For each qid the user with lower time gets a point and total point is sum of all the points. Below query just returns the total attempts for each user, need a way to return the points.
Incorrect Query=select user, count(*) from (select * from (select * from xyz order by
time ASC) as temp1 group by temp1.user,temp1.qid) AS temp2 group by user
DB:
CREATE TABLE xyz (
id INT PRIMARY KEY AUTO_INCREMENT,
user VARCHAR(20),
time INT,
qid INT
);
INSERT INTO xyz VALUES ( 1 , 'abc' , 15 , 1);
INSERT INTO xyz VALUES ( 2 , 'abc' , 6 , 1);
INSERT INTO xyz VALUES ( 3 , 'xyz' , 11 , 1);
INSERT INTO xyz VALUES ( 4 , 'abc' , 4 , 1);
INSERT INTO xyz VALUES ( 5 , 'xyz' , 13 , 2);
INSERT INTO xyz VALUES ( 6 , 'abc' , 11 ,2);
INSERT INTO xyz VALUES ( 7 , 'abc' , 9 , 3);
INSERT INTO xyz VALUES ( 8 , 'xyz' , 10 , 3);
INSERT INTO xyz VALUES ( 9 , 'xyz' , 2 , 3);
INSERT INTO xyz VALUES ( 10 , 'xyz' , 2 , 4);
Expected output:
USER Score
abc 2
xyz 2
Output Explanation:
For qid=1, abc has lower time so 1 point to abc
For qid=2, abc has lower time so 1 point to abc
For qid=3, xyz has lower time so 1 point to xyz
For qid=4, xyz has lower time so 1 point to xyz
sqlfiddle Link

You need to find the number of times that a user is "first" for each qid. Here is one method:
select xyz.user, count(*) as score
from xyz join
(select qid, min(time) as mintime
from xyz
group by qid
) q
on xyz.qid = q.qid and xyz.time = q.mintime
group by xyz.user;

Related

Case with multiple records

I have a data set which looks like this:
id No_trans Bank
1 2 VISA
1 1 PAYPAL
2 3 MASTERCARD
3 1 MASTERCARD
3 4 PAYPAL
4 1 PAYPAL
What I need to do is if id has PAYPAL, change it to another bank, for example.
For id = 1, PAYPAL should be as VISA, but for id = 3, it should be MASTERCARD, however, for id = 4, it should be PAYPAL because it doesn't have another Bank record.
select id ,count(No_trans) ,
case Bank when PAYPAL then VISA
when PAYPAL then MASTERCARD
else
PAYPAL
end as bank
from table
Grouping by 1 and 3
is not going to work, because I need to change it depending on which other record has the same id bank.
If this ID has a bank different from PAYPAL, use it for other records with the same ID, if not, use it as it is.
create temporary table t1
(
ID INT
, no_trans int
, bank varchar (255)
);
INSERT INTO t1 values
(1, 2 , 'VISA'),
(1 , 1 , 'PAYPAL'),
(2, 3 , 'MASTERCARD'),
(3 , 1 , 'MASTERCARD'),
(3, 4 , 'PAYPAL'),
(4 , 1 , 'PAYPAL');
select * from t1
where id = 1
return
'1','2','VISA'
'1','1','PAYPAL'
I need
'1','2','VISA'
'1','1','VISA'
for
select * from t1
where id = 3
should be
ID, no_trans, bank
3, 1, MASTERCARD
3, 4, MASTERCARD
for
select * from t1
where id = 4
ID, no_trans, bank
4, 1, PAYPAL
You can use aggregation:
select id,
coalesce(max(case when Bank <> 'PayPal' then Bank end),
max(Bank)
)
from t
group by id;
If you want the original rows, then perhaps a subquery is simpler:
select t.*,
(select t2.bank
from t t2
where t2.id = t.id
order by (t2.bank <> 'PayPal) desc
limit 1
) as new_bank
from t;
Try the following:
select
ID,
no_trans,
If (id = 1 and bank = 'PAYPAL', 'VISA',bank)as bank
from t1
where id = 1
For Id = 3
select
ID,
no_trans,
If (id = 3 and bank = 'PAYPAL', 'MATERCARD',bank) as bank
from t1
where id = 3;
If you need all of them combined:
select
ID,
no_trans,
If (bank = 'PAYPAL',If(id = 1,'VISA',If(id=3,'MASTERCARD',bank)),bank) as bank
from t1;
SQLFIDDLE DEMO

Multi Level Marketing SQL Query to calculate turnover of the team

I have a users table that looks someting like this :
ID NAME
1 Robin
2 Edward
3 Donald
4 Julie
The 2nd table user_tree
ID USER_ID TREE
1 1 ["2","3","4"]
2 2 ["3","4"]
3 3 ["4"]
4 4 []
The 3rd table orders
ID AMOUNT USER_ID
1 150 2
2 300 3
3 200 4
4 500 3
the expected result, get the following table (create table mlm_team as select..) with a SQL query
ID USER_ID TEAM_SUM
1 1 1150
2 2 1000
3 3 200
Is there an SQL expert who can help me?
Follow below step:
- Create table and insert record.
- Get JSON type for array value
- Use "JSON_CONTAINS" for find MLM chain
Explain here:
create table users(id int, name varchar(50));
create table user_tree(id int, user_id int, tree json );
create table orders(id int, amount int, user_id int);
insert into users values(1, 'Robin');
insert into users values(2, 'Edward');
insert into users values(3 , 'Donald');
insert into users values(4 , 'Julie');
select * from users;
insert into user_tree values(1, 1 , '["2","3","4"]');
insert into user_tree values(2 , 2 , '["3","4"]');
insert into user_tree values(3 , 3 , '["4"]');
insert into user_tree values(4 , 4 , '[]');
select * from user_tree;
insert into orders values(1 , 150 , 2);
insert into orders values(2 , 300 , 3);
insert into orders values(3 , 200 , 4);
insert into orders values(4 , 500 , 3);
select * from orders;
- Final Query here:
SELECT u1.id, u1.user_id as user_id, sum(amount)
FROM user_tree u1
left outer join user_tree u2 on JSON_CONTAINS(u1.tree, concat('["', u2.user_id ,'"]'))
left outer join orders o1 on o1.user_id = u2.user_id
where u2.user_id
group by u1.id, u1.user_id
order by u1.id;
Find SQL Fiddle details from here LINK.

MySQL: Selecting where only one unique Max record exists

My data is:
bid_id, fkp_id, fkb_id, bid_amount
1 , 13 , 1 , 22000
2 , 13 , 2 , 23000
3 , 13 , 2 , 23000
4, 3 , 1 , 5000
5, 3 , 2 , 6000
If there is a tie (in this case bid_id 2 and bid_id 3) this record should not be selected and only unique max bid_amount value record should be selected.
in this case desired record is bid_id 1 and bid_id 5
Looking to your data if you need all with one unique max amount
and the max amount is related to the amount itself you could use
select bid_id, fkp_id, fkb_id, bid_amount
from table_name
where bid_amount = ( select max(t.bid_amount)
from ( select bid_amount, count(*)
from table_name
group by bid_amount
having count(*) = 1 ) t )
If your unique max amount is for flp_id then you shoulf group by properly for this columns too
select bid_id, fkp_id, fkb_id, bid_amount
from table_name
where ( fkp_id, bid_amount) in ( select t.fkp_id, max(t.bid_amount)
from ( select fkp_id, bid_amount, count(*)
from table_name
group by fkp_id, bid_amount
having count(*) = 1 ) t
group by t.fkp_id )

Querying with SQL

I am trying to write a query in sql which gives me distinct Pan details and the count of that Pan in the table where the Name is appearing more than once
For example: Consider the table below
ID Name Pan
1 ABC 123
2 ABC 123
3 DEF 456
4 ABC 124
5 WW 234
6 WW 2345
The result expected is :
Pan Name Count1
123 ABC 2
124 ABC 1
234 WW 1
2345 WW 1
Could someone please help me out with this.
Try this. Hope below statement help you out.
SELECT PAN, NAME , COUNT(ID) FROM TAB_PAN GROUP BY PAN, NAME HAVING COUNT(ID)>1
As per conversation the requirement seems different.
The below code will work fine.
Schema for given data
SELECT * INTO #TAB FROM (
SELECT 1 ID , 'ABC' NAME , 123 PAN
UNION ALL
SELECT 2, 'ABC', 123
UNION ALL
SELECT 3 , 'DEF' ,456
UNION ALL
SELECT 4 , 'ABC', 124
UNION ALL
SELECT 5 , 'WW' , 234
UNION ALL
SELECT 6 , 'WW' ,2345
)AS A
Logic for the required case
SELECT PAN, NAME,COUNT(ID) ACTUAL_COUNT FROM #TAB t
WHERE (SELECT COUNt(NAME) FROM #TAB WHERE NAME= t.NAME) >1
GROUP BY PAN, NAME
SELECT DISTINCT x.*
FROM
( SELECT pan
, name
, COUNT(*) total
FROM my_table
GROUP
BY pan
, name
) x
JOIN my_table y
ON y.name = x.name
AND y.pan <> x.pan

How to query Sql Db to get the students' result for only those who complete all exam's stages

ExamsStagesTbl
CourseId StageId
1 1
1 2
2 1
3 1
3 2
3 3
3 4
StudentsResultTbl
StudentId CourseId StageId StageDgree
23 1 1 30
23 1 2 25
23 3 1 30
10 1 1 27
10 2 1 30
Please how to get all records from the table StudentsResultTbl for only those finish all the exam's stages.
the Scenario:
from the above tables:
Student 23 has exam in courses 1 and 3 but he only finish course 1.
Student 10 has exam in course 1 and 2 but he only finish course 2.
so how to get the result(if the student has exam in all course's stages) using SQL statement
Try this:
DECLARE #courses TABLE
(
CourseID INT ,
StageID INT
)
DECLARE #results TABLE
(
StudentID INT ,
CourseID INT ,
StageID INT
)
INSERT INTO #courses
VALUES ( 1, 1 ),
( 1, 2 ),
( 2, 1 ),
( 3, 1 ),
( 3, 2 ),
( 3, 3 ),
( 3, 4 )
INSERT INTO #results
VALUES ( 23, 1, 1 ),
( 23, 1, 2 ),
( 23, 3, 1 ),
( 10, 1, 1 ),
( 10, 2, 1 );
WITH cte1
AS ( SELECT CourseID ,
COUNT(*) AS StageCount
FROM #courses c
GROUP BY CourseID
),
cte2
AS ( SELECT StudentID ,
CourseID ,
COUNT(DISTINCT StageID) AS StageCount
FROM #results c
GROUP BY StudentID ,
CourseID
)
SELECT cte2.StudentID ,
cte2.CourseID
FROM cte2
JOIN cte1 ON cte1.CourseID = cte2.CourseID
WHERE cte1.StageCount = cte2.StageCount
ORDER BY cte2.StudentID ,
cte2.CourseID
Output:
StudentID CourseID
10 2
23 1
select d.studentid,c.courseid from (select courseid,count(*) as no from studentcompleteallstages group by courseid) c inner join ( select studentid,courseid ,count(*) as no
from (select b.studentid,b.courseid,b.stageid from studentcompleteallstages a inner join tblstudents b on a.courseid=b.courseid and a.stageid=b.stageid
) as sub group by studentid,courseid ) d on c.courseid = d.courseid and c.no=d.no