I have following mysql tabels
tbl_users
user_id email db_add_date
1 steve#gmail.com 2014-04-22 19:32:35
2 mark#gmail.com 2014-05-02 10:12:01
3 allan#yahoo.com 2014-03-15 05:14:56
4 jim_ross#gmail.com 2014-02-12 14:10:08
tbl_points
id user_id points
1 1 10
2 3 1
3 2 15
4 1 16
5 4 46
6 3 24
i want to fetch those email & points that are single
Expected Result
email userid points
mark#gmail.com 2 15
jim_ross#gmail.com 4 46
please help...
UPDATE DESCRIPTION
I want to fetch those email records that having only 1 entry in points table
SQL Fiddle
MySQL 5.5.32 Schema Setup:
create table tbl_users
(
user_id int,
email varchar(20),
db_add_date datetime
);
insert into tbl_users values
(1, 'steve#gmail.com ', '2014-04-22 19:32:35'),
(2, 'mark#gmail.com ', '2014-05-02 10:12:01'),
(3, 'allan#yahoo.com ', '2014-03-15 05:14:56'),
(4, 'jim_ross#gmail.com', '2014-02-12 14:10:08');
create table tbl_points
(
id int,
user_id int,
points int
);
insert into tbl_points values
(1, 1, 10),
(2, 3, 1 ),
(3, 2, 15),
(4, 1, 16),
(5, 4, 46),
(6, 3, 24);
Query 1:
select u.email,
u.user_id,
p.points
from tbl_users as u
inner join (
select user_id,
sum(points) as points
from tbl_points
group by user_id
having count(*) = 1
) as p
on u.user_id = p.user_id
Results:
| EMAIL | USER_ID | POINTS |
|--------------------|---------|--------|
| mark#gmail.com | 2 | 15 |
| jim_ross#gmail.com | 4 | 46 |
your Expected Result...!!!
(Simple and sort query)
SELECT u.email,u.user_id as userid,p.points
FROM tbl_users u
LEFT JOIN tbl_points p
ON u.user_id = p.user_id
GROUP BY u.user_id
HAVING COUNT(u.user_id) = 1
Result:-
> email userid points
> mark#gmail.com 2 15
> jim_ross#gmail.com 4 46
Related
Refer to another Stack Overflow question here, however the answers there didn't include the group_id 3 player.
I tried to replicate the answer in MySQL but I am not familiar with PostgreSQL. Anyone can show how to proceed it in MySQL?
The question is to return the max scored player as winner_id from each group
create table players (
player_id integer not null unique,
group_id integer not null
);
create table matches (
match_id integer not null unique,
first_player integer not null,
second_player integer not null,
first_score integer not null,
second_score integer not null
);
insert into players values(20, 2);
insert into players values(30, 1);
insert into players values(40, 3);
insert into players values(45, 1);
insert into players values(50, 2);
insert into players values(65, 1);
insert into matches values(1, 30, 45, 10, 12);
insert into matches values(2, 20, 50, 5, 5);
insert into matches values(13, 65, 45, 10, 10);
insert into matches values(5, 30, 65, 3, 15);
insert into matches values(42, 45, 65, 8, 4);
matches table
match_id | first_player | second_player | first_score | second_score
----------+--------------+---------------+-------------+--------------
1 | 30 | 45 | 10 | 12
2 | 20 | 50 | 5 | 5
13 | 65 | 45 | 10 | 10
5 | 30 | 65 | 3 | 15
42 | 45 | 65 | 8 | 4
Expected output
group_id | winner_id
----------+-----------
1 | 45
2 | 20
3 | 40
I presume that since you can't use the solution to the other question that you are using MySQL 5.7 or below. In that case, you have to simulate the ROW_NUMBER/PARTITION functionality, which you can do with a LEFT JOIN from a derived table of scores per player with itself, joining on the score being greater than that in the first table. Any player who has no scores greater in the joined table clearly has the highest score. Since there can be ties, we then take the minimum of the player_id values from that table (when there is no tie, this has no effect).
SELECT group_id, MIN(player_id) AS player_id
FROM (
SELECT t1.group_id, t1.player_id
FROM (
SELECT p.player_id, p.group_id,
SUM(CASE WHEN m.first_player = p.player_id THEN m.first_score
ELSE m.second_score
END) AS score
FROM players p
LEFT JOIN matches m ON m.first_player = p.player_id OR m.second_player = p.player_id
GROUP BY p.player_id, p.group_id
) t1
LEFT JOIN (
SELECT p.player_id, p.group_id,
SUM(CASE WHEN m.first_player = p.player_id THEN m.first_score
ELSE m.second_score
END) AS score
FROM players p
LEFT JOIN matches m ON m.first_player = p.player_id OR m.second_player = p.player_id
GROUP BY p.player_id, p.group_id
) t2 ON t2.group_id = t1.group_id AND t2.score > t1.score
GROUP BY t1.group_id, t1.player_id
HAVING COUNT(t2.player_id) = 0
) w
GROUP BY group_id
Output:
group_id player_id
1 45
2 20
3 40
Demo on db-fiddle
I have a table like this
idGoal | idMatch | minute
1 | 1 | 30
2 | 1 | 40
3 | 2 | 30
4 | 3 | 45
I want to get only the goals where the minute are the same on distinct matches.
So it shows idGoal 1 and 3.
I would use exists:
select g.*
from goals g
where exists (select 1
from goals g2
where g2.minute = g.minute and
g2.idMatch <> g.idMatch
);
In particular, exists can take advantage of an index on (minute, idMatch).
Your table:
CREATE TABLE goals
(idGoal INT, idMatch INT, minute TINYINT);
Your data:
INSERT INTO goals
(idGoal, idMatch, minute)
VALUES
(1, 1, 30),
(2, 1, 40),
(3, 2, 30),
(4, 3, 45);
Your query:
SELECT idGoal
FROM goals
WHERE minute IN
(
SELECT minute
FROM goals
GROUP BY minute
HAVING COUNT(*) > 1
);
Your result:
idGoal
------
1
3
I am quiet new to programming so i need some help for the query in the below scenario.
user table
uid (PK)| name | score
------------------
1 | john | 20
2 | mary | 40
3 | david | 60
4 | nancy | 80
question_tb table
qid|question
-------------
1 | a
2 | b
3 | c
4 | d
question_user table
quid | user_id (FK) | question_id (FK)
--------------------------------
1 | 1 | 1
2 | 2 | 1
3 | 1 | 2
4 | 3 | 3
As above shows the table structure of the database. question_user table holds the questions that have been answered by a particular user. I want to get the list of questions in DESC manner that particular user has not been answered.
The following query should give you questions that user hasn't answered.
SELECT *
FROM question_tb as q
LEFT JOIN question_user as qu on q.qid = qu.question_id AND qu.user_id = USER_ID_HERE
WHERE qu.user_id IS NULL;
If you want to get the Questions not answered by particular user in DESC then use below query
SELECT * FROM questions WHERE qid NOT IN (SELECT question_id FROM `question_user` WHERE uid = USER-ID) ORDER BY qid DESC;
Try this:
Sample data:
create table users (uid int, name varchar(10), score int);
insert into users values
(1, 'john', 20),
(2, 'mary' , 40),
(3, 'david', 60),
(4, 'nancy', 80);
create table question_tb (qid int, question char(1));
insert into question_tb values
(1, 'a'),
(2, 'b'),
(3, 'c'),
(4, 'd');
create table question_user (quid int, user_id int, question_id int);
insert into question_user values
(1, 1, 1),
(2, 2, 1),
(3, 1, 2),
(4, 3, 3);
T-SQL:
select uid, qid from users u
cross join question_tb q
where not exists(
select 1 from question_user
where u.uid = user_id and q.qid = question_id)
order by uid, qid
Table:
id driver_id status
1 23 1
2 23 1
3 22 1
4 23 0
5 22 1
6 22 1
7 22 0
8 22 1
9 23 1
I want a select query to check driver_id with status 1, consequently three or more times, with total count and id
for above table result should be like:
id driver_id status total_count
3 22 1 3
5 22 1 3
6 22 1 3
because driver_id having status 1 three times without any other status like 0, not 23 because having status 1 at id 1 and id 2 and having status 0 at id 4 so total count < 3 .
This is my original table:
In this table i am checking for status 52
I have to fetch drivers who cancelled trip => 3 times in a row
/*
DROP TABLE T;
CREATE TABLE T(id INT,driver_id INT, status INT);
TRUNCATE TABLE T;
INSERT INTO T VALUES
(1, 23, 1),
(2, 23, 1),
(3, 22, 1),
(4, 23, 0),
(5, 22, 1),
(6, 22, 1),
(7, 22, 0),
(8, 22, 1),
(9, 23, 0);
*/
SELECT T.ID,T.DRIVER_ID,T.STATUS,S.RN Total_count FROM
(
SELECT U.BN,MAX(U.RN) RN FROM
(
SELECT T.*,
IF(CONCAT(T.DRIVER_ID,STATUS) = #PREV,#BN,#BN:=#BN+1) BN,
IF(CONCAT(T.DRIVER_ID,STATUS) <> #PREV,#RN:=1,#RN:=#RN+1) RN,
#PREV:=CONCAT(T.DRIVER_ID,STATUS) P
FROM (SELECT #RN:=0,#BN:=0,#PREV:='') RN, T
ORDER BY DRIVER_ID,ID
) U
WHERE U.RN >= 3
GROUP BY U.BN
) S
JOIN
(SELECT T.*,
IF(CONCAT(T.DRIVER_ID,STATUS) = #PREV1,#BN1,#BN1:=#BN1+1) BN,
IF(CONCAT(T.DRIVER_ID,STATUS) <> #PREV1,#RN1:=1,#RN1:=#RN1+1) RN,
#PREV1:=CONCAT(T.DRIVER_ID,STATUS) P
FROM (SELECT #RN1:=0,#BN1:=0,#PREV1:='') RN, T
ORDER BY DRIVER_ID,ID) T ON T.BN = S.BN
ORDER BY T.DRIVER_ID,T.ID
result
+------+-----------+--------+-------------+
| ID | DRIVER_ID | STATUS | Total_count |
+------+-----------+--------+-------------+
| 3 | 22 | 1 | 3 |
| 5 | 22 | 1 | 3 |
| 6 | 22 | 1 | 3 |
+------+-----------+--------+-------------+
SELECT `id`,`driver_id`,`status`,COUNT(`driver_id`) FROM `t` WHERE `status`<>0 GROUP BY `driver_id`;
I'm trying to use a LEFT JOIN in conjunction with a GROUP_CONCAT but not getting the expected results.
Two simple tables:
weather_alerts:
id | user_id | resort_id
1 | 1 | 1
2 | 1 | 2
3 | 1 | 3
4 | 1 | 5
weather_users
id | email
1 | me#me.com
The query:
SELECT GROUP_CONCAT(wa.resort_id) AS resort_ids, wu.email FROM weather_alerts wa LEFT JOIN weather_users wu ON wa.id = wu.user_id GROUP BY wu.email
Instead of generating:
email resort_ids
me#me.com 1,2,3,5
I get:
email resort_ids
NULL 2,3,5
me#me.com 1
I suspect this is an issue with the JOIN rather than the CONCAT.
It appears that your LEFT JOIN needs improvement.
create table weather_alerts (id int, user_id int, resort_id int);
insert into weather_alerts values (1, 1, 1), (2, 1, 2), (3, 1, 3), (4, 1, 5);
create table weather_users (id int, email varchar(100));
insert into weather_users values (1, 'me#me.com');
Query
SELECT GROUP_CONCAT(wa.resort_id ORDER BY wa.resort_id) AS resort_ids, wu.email
FROM weather_alerts wa
LEFT JOIN weather_users wu ON wa.user_id = wu.id
GROUP BY wu.email
Notice that you are joining on wa.id = wu.user_id. The join should be on wa.user_id = wu.id
Result
| resort_ids | email |
|------------|-----------|
| 1,2,3,5 | me#me.com |