Can't work out MySQL Query - mysql

I have a MySQL table which has the following data.
surveyid | staff | username | ipaddress | rating | comments
---------|--------|----------|-----------|---------|----------
0 | staff1 | user1 | 1.1.1.1 | 10 | none
1 | staff2 | user2 | 1.2.1.1 | 5 | none
2 | staff2 | user3 | 1.2.1.1 | 10 | none
3 | staff2 | user2 | 1.2.1.1 | 6 | none
4 | staff3 | user4 | 1.1.1.51 | 10 | none
5 | staff4 | user3 | 1.21.12.1 | 9 | none
6 | staff5 | user2 | 1.12.1.1 | 10 | none
I am wanting a query that will select surveyid, staff, username and ipaddress only when an ipaddress has been used for multiple users for the same staff.
Basicly I am wanting to find out what staff has multiple users submit off the same ip address.
I have tried the following but it does not work.
SELECT * FROM `comment_data` CD
INNER JOIN
(SELECT `ipaddress`, COUNT(DISTINCT `staff`)
FROM `comment_data` GROUP BY `ipaddress` HAVING COUNT(DISTINCT `staff`) > 1 )
USECOUNT ON USECOUNT.`ipaddress` = CD.`ipaddress`
I also tried the following query.
SELECT * FROM `commend_data` WHERE `staff`+`ipaddress` IN
(SELECT `staff`+`ipaddress` FROM `comment_data` GROUP BY `staff`, `ipaddress`
HAVING COUNT(`surveyid`) > 1)
Also I want to make sure I display all duplicates and I don't want to display just counts.
If you need any more information please ask.
Thanks
Paul

select surveyid, staff, username, ipaddress
from table1
where ipaddress+staff in
(
select ipaddress+staff
from table1
group by ipaddress,staff
having count(surveyid)>1
)
SQL FIDDLE

SELECT surveyid,
PT.staff,
username,
PT.ipaddress
FROM PaulTable PT
INNER JOIN
(
SELECT ipaddress, staff
FROM PaulTable
GROUP BY ipaddress, staff
HAVING COUNT(DISTINCT username) > 1
) USECOUNT
ON USECOUNT.ipaddress = PT.ipaddress
AND USECOUNT.staff = PT.staff

Related

When I use "WHERE user_id in ( sub query )" generate syntax error

I have a users table used below.
Users have referal_code, refered_by columns.Users has following data.
+----+--------------+------------+
| id | referal_code | refered_by |
+----+--------------+------------+
| 1 | abc | null |
| 2 | xxx | abc |
+----+--------------+------------+
I have Reviews table in which I store users reviewe by other users.
It does have user_id, evaluation columns.
+----+---------+------------+
| id | user_id | evaluation |
+----+---------+------------+
| 28 | 2 | 4 |
| 32 | 2 | 6 |
+----+---------+------------+
I'm trying to count users referred by each user have an average evaluation of 3 or more.
SELECT users.*, COUNT(
SELECT reviews.user_id FROM reviews
WHERE reviews.user_id IN(
SELECT A2.id FROM users as A2 WHERE A2.refered_by = users.referal_code
)
HAVING AVG(evaluation) >= 3) as total_3_estrelas
FROM users
WHERE 1
I have a syntax error #1064 on: WHERE user_id IN
The result I expect:
+----+--------------+------------+------------------+
| id | referal_code | refered_by | total_3_estrelas |
+----+--------------+------------+------------------+
| 1 | abc | null | 1 |
| 2 | xxx | abc | 0 |
+----+--------------+------------+------------------+
Look at this if it helps:
SELECT A.ID, A.REFERAL_CODE, A.REFERED_BY, COALESCE(TOTAL_3_ESTRELAS,0) AS TOTAL_3_ESTRELAS
FROM USERS A
LEFT JOIN
(SELECT REFERED_BY, COUNT(*) AS TOTAL_3_ESTRELAS
FROM USERS U
INNER JOIN (SELECT USER_ID, AVG(EVALUATION)
FROM REVIEWS
GROUP BY USER_ID
HAVING AVG(EVALUATION)>=3) R
ON U.ID=R.USER_ID
GROUP BY REFERED_BY) T
ON A.REFERAL_CODE=T.REFERED_BY;
From the deeper nested condition, first I calculated the average evaluation for each user_id on REVIEWS throwing away USER_ID with avg below 3, then I made the inner join with USERS and I grouped by REFERED_BY to obtain the count desired. Finally I did a left join to obtain the output in the form you expect.

MySQL GroupBy with null/zero results

I'm currently writing a ticket system that has three tables
one for users:
users
+----+-----------+----------+
| ID | FirstName | LastName |
+----+-----------+----------+
| 1 | First | User |
| 2 | Second | User |
| 3 | Third | User |
| 4 | Fourth | User |
| 5 | Fifth | User |
+----+-----------+----------+
one for tickets:
ticket
+----+---------------+
| ID | TicketSubject |
+----+---------------+
| 1 | Ticket #1 |
| 2 | Ticket #2 |
| 3 | Ticket #3 |
| 4 | Ticket #4 |
+----+---------------+
and one to assign users to tickets to action (can be more than one user per ticket):
ticket_assigned
+----+----------+--------+
| ID | TicketID | UserID |
+----+----------+--------+
| 1 | 1 | 1 |
| 2 | 1 | 2 |
| 3 | 2 | 1 |
| 4 | 3 | 5 |
| 5 | 3 | 3 |
+----+----------+--------+
I'm trying to create a summary to show each user, and how many tickets they have assigned to them, example:
+------------+-------+
| Name | Count |
+------------+-------+
| First | 2 |
| Second | 1 |
| Third | 1 |
| Fourth | 0 |
| Fifth | 1 |
| Unassigned | 2 |
+------------+-------+
Note that the last entry is "unassigned", this is the number of records in the ticket table that DONT appear in the ticket_assigned table (thus being, unassigned). Also further note that user "Fourth" is zero, in that that user has no records in the ticket_assigned table.
Here is the current MySQL query I am using:
SELECT
CASE
WHEN users.FirstName IS NULL
THEN 'Unassigned'
ELSE users.FirstName
END as 'UserName',
COUNT(*) as 'TicketCount'
FROM tickets
LEFT OUTER JOIN ticket_assigned ON tickets.ticket_id = ticket_assigned.ticket_id
LEFT OUTER JOIN users ON ticket_assigned.user_id = users.user_id
GROUP BY ticket_assigned.user_id
ORDER BY UserName;
Problem with this is that it's not showing any of the users that don't feature in the ticket_assigned table, I'm essentially getting this:
+------------+-------+
| Name | Count |
+------------+-------+
| First | 2 |
| Second | 1 |
| Third | 1 |
| Fifth | 1 |
| Unassigned | 2 |
+------------+-------+
Is anyone able to assist and tell me how I can modify my query to include users that have no records in the ticket_assigned table? Thanks in advance!
Use a LEFT JOIN with a subquery to aggregate tickets:
SELECT t1.FirstName,
COALESCE(t2.ticket_count, 0) AS num_tickets
FROM users t1
LEFT JOIN
(
SELECT UserID, COUNT(*) AS ticket_count
FROM ticket_assigned
GROUP BY UserID
) t2
ON t1.ID = t2.UserID
UNION ALL
SELECT 'Unassigned', COUNT(*)
FROM tickets t
WHERE NOT EXISTS (SELECT 1 FROM tickets_assigned ta
WHERE ta.ticketId = t.id)
In MySQL, I think you need a left join and union all:
select u.id, u.firstname, count(ta.userId) as num_tickets
from users u left join
tickets_assigned ta
on ta.userId = u.id
group by u.id, u.firstname
union all
select NULL, 'Unassigned', count(*)
from tickets t
where not exists (select 1
from tickets_assigned
where ta.ticketId = t.id
);
I included the u.id in the aggregations. I'm uncomfortable just aggregating (and reporting) by first name, because different people frequently have the same first name, even in a relatively small group.
SELECT
u2.Firstname, IFNULL(tmp.count, 0) AS count
FROM users u2
LEFT JOIN (
SELECT u.id, u.Firstname, COUNT(1) as count
FROM ticket_assigned ta
LEFT JOIN ticket t ON t.id = ta.ticketID
LEFT JOIN users u ON u.id = ta.userID
GROUP BY u.id
) tmp ON tmp.id = u2.id
UNION
SELECT
'Unassigned', count(1) AS count
FROM ticket
WHERE id NOT IN (SELECT ticketid FROM ticket_assigned)

SQL: Remove rows with a duplicate field

I have duplicate entries due to a programming error.
Table Example:
id | group | userNum | username | name
---------------------------------------
1 | AA11 | D-01 | user1 | Donald
2 | AA11 | D-02 | user2 | Cruz
3 | AA11 | D-03 | user3 | Rubio
4 | AA11 | D-01 | user1 | Donald <------DUPLICATE
5 | AA11 | D-04 | user4 | Cruz
6 | AA22 | D-03 | user2 | Rubio
7 | AA22 | D-02 | user1 | Donald
userNum, username must be unique to each group, but a group can have userNum, username, name which are found in other groups.
A standard SQL approach is to use a subquery in the WHERE clause. For instance:
delete from example
where id not in (select min(id)
from example e2
group by group, userNum, username, name
);
This doesn't work in MySQL. You can do something similar using left join:
delete e
from example e left join
(select min(id) as minid
from example e2
group by group, userNum, username, name
) ee
on e.id = ee.minid
where ee.minid is null;
Add group by userNum, username, group at the end of your query..

SQL query to get my followers except me

I try to make a sql query to get all my followers except me.
I have the following tables:
users
| id_user | username |
| 1 | xaxa |
| 2 | toto |
| 3 | bubu |
| 4 | yiyi |
| 5 | pepe |
| 6 | sisi |
| 7 | fifi |
| 8 | mama |
| 9 | juju |
| 10 | cece | => me
friends
| id_friend | id_user | id_user_to |
| 1 | 10 | 1 |
| 2 | 2 | 10 |
| 3 | 2 | 1 |
| 4 | 6 | 3 |
| 5 | 2 | 9 |
| 6 | 6 | 7 |
| 7 | 5 | 3 |
| 8 | 10 | 5 |
| 9 | 9 | 8 |
| 10 | 8 | 10 |
I want to have this:
my friends
| id_user | name |
| 1 | xaxa |
| 2 | toto |
| 5 | pepe |
| 8 | mama |
actually I have id_user 10 (me) in the result with this query =>
SELECT id_user, name
FROM `users`
WHERE id_user NOT IN (
SELECT `id_user` FROM `friends`
WHERE ( `id_user` = 10 OR `id_user_to` = 10 ))
OR id_user NOT IN (
SELECT `id_user_to` FROM `friends`
WHERE ( `id_user` = 10 OR `id_user_to` = 10 ))
GROUP BY `id_user`
The solution is a union of two simple joins:
SELECT u.id_user, u.username name
FROM friends f
JOIN users u ON u.id_user = f.id_user_to
WHERE f.id_user = 10
UNION
SELECT u.id_user, u.username
FROM friends f
JOIN users u ON u.id_user = f.id_user
WHERE f.id_user_to = 10
Note that the keyword UNION removes duplicates from the result, so no need to code anything special to handle the case when there's a friend link in both directions between two users (FYI, UNION ALL retains duplicates).
Because at most one index is used per table per query, by splitting the query into two parts, if indexes are created on the user id columns of the friends table, this query will scale well (to millions of users)
There was no need to code anything to handle an "except me" condition, unless you have a row in the friends table for you being your own friend, which you don't.
SqlFiddle: http://sqlfiddle.com/#!9/7cbb3/4
This should do:
SELECT u.id_user, u.username name
FROM `friends` f
JOIN `users` u
ON u.id_user = f.id_user_to and f.id_user = 10
or u.id_user = f.id_user and f.id_user_to = 10
ORDER BY u.id_user
SqlFiddle: http://sqlfiddle.com/#!9/7cbb3/1
So essentially you need to get users who are related in either direction (id_user -> id_user_to OR id_user_to -> id_user)
You can do either one of those with these queries:
SELECT friends.id_user, users.name
FROM users
JOIN friends on users.id_user = friends.id_user
WHERE friends.id_user_to = 10
SELECT friends.id_user_to, users.name
FROM users
JOIN friends on users.id_user = friends.id_user
WHERE friends.id_user = 10
But you want both sides. One way to do it is to do both queries and UNION them together. You could do it like this whilst also adding in the names
SELECT friends.id_user, users.name
FROM users
JOIN friends on users.id_user = friends.id_user
WHERE friends.id_user_to = 10
UNION
SELECT friends.id_user_to, users.name
FROM users
JOIN friends on users.id_user = friends.id_user
WHERE friends.id_user = 10
It's also worth noting that the UNION will only show you distinct rows so if you have users in both directions (for example 1 -> 10 and 10 -> 1) they will not show twice.

MySQL Query Join to select unmatched rows from two tables

I have two tables as below.
user_id | username | first_name | role_type
-----------------------------------------------------------
1 | testuser1 | testu1 | student
2 | testuser2 | testu2 | student
3 | testuser3 | testu3 | student
4 | testuser4 | testu4 | student
5 | testuser5 | testu5 | student
6 | testuser6 | testu6 | admin
7 | testuser7 | testu7 | admin
-----------------------------------------------------------
user_id | username | approved_id
----------------------------------------------------------------------
1 | testuser1 | 3B888F52-50BC-11E2-B08B-99E5B2CADDF7
2 | testuser2 | 3B888F52-50BC-11E2-B08B-99E5B2CADDF7
3 | testuser3 | 3B888F52-50BC-11E2-B08B-99E5B2CADDF7
----------------------------------------------------------------------
I tried the query
SELECT users.* FROM users
WHERE users.username NOT IN(
SELECT users_approval.username FROM users_approval
WHERE users_approval.approved_id = "3B888F52-50BC-11E2-B08B-99E5B2CADDF7"
) AND users.role_type = "student"
and got the result below
user_id | username | first_name | role_type
-------------------------------------------------------------
4 | testuser4 | testu4 | student
5 | testuser5 | testu5 | student
-------------------------------------------------------------
Is there any way to use JOIN to fetch the same resultset as above ?.
Help is much appriciated.
SELECT users.*
FROM users
LEFT JOIN users_approval b
ON users.username = b.username AND
b.approved_id = "3B888F52-50BC-11E2-B08B-99E5B2CADDF7"
WHERE users.role_type = "student" AND
b.approved_id IS NULL
SQLFiddle Demo
SELECT
users.*
FROM users as u
LEFT JOIN users_approval as ua ON ua.id = u.id
WHERE u.role_type = "student" AND ua.approved_id IS NULL
Assuming you have user_id as foreign key in the second table it can be used to join instead of using username to join table