I am trying to select distinct users that are listed for other companies but not on my company (1). Here is an example
Placement User Company
1 1 1
2 1 2
3 2 2
4 3 1
5 2 1
From this table, I would like to get row 4 since he is in other company (not 1) but listed on others. I do not want others because they are listed on both my company and others. Anyone can help?
You can use NOT IN. For example:
select distinct user
from t
where user not in (
select user from t where company = 1
)
I think that this is the logic that you want:
select t.*
from mytable t
where not exists (
select 1 from mytable t1 where t1.user = t.user and t1.company = 1
)
This gives you the records for which no other record exists for the same user and company 1.
Related
My tables look like this. my op and country is having many to many relationships with each other.
OP
id, name,.....
op_country
id, op_id, country_id
country
id, name, ...
my op_country filled like below
id op_id country_id
1 1 1
2 1 2
3 2 2
4 2 3
5 3 3
6 3 3
7 1 1
I want to remove my duplicate entries from op_country. Here I want to remove rows 6 and 7 since we already have rows with such values.
How can I do that.
DELETE t1
FROM op_country t1
JOIN op_country t2 USING (op_id, country_id)
WHERE t1.id > t2.id
https://dbfiddle.uk/?rdbms=mysql_8.0&fiddle=247ebc5870a6ab10b64076ffb375797f
You want to delete entries for which exists a sibling with a lower ID:
delete from op_country
where exists
(
select null
from (select * from op_country) op2
where op2.op_id = op_country.op_id
and op2.country_id = op_country.country_id
and op2.id < op_country.id
);
The from (select * from op_country) is necessary instead of a mere from op_country due to some weird restriction in MySQL updates.
I would like to count(*) how much customers have created a post or made a comment. If the same customer has made several posts and comments, it should count only once.
Customer Table:
ID Name ...
1 Jonh
2 Mark
3 King
4 Doe
Post Table:
ID USER_ID...
1 1
2 1
3 3
4 1
Comment Table:
ID USER_ID...
1 1
2 3
3 3
4 4
It should return count(*) = 3
(user_id: 1, 3 and 4).
Try this one. It worked for me and returns what you're looking for:
SELECT COUNT( USER_ID ) AS TOTAL
FROM (
SELECT USER_ID
FROM POSTS
UNION
SELECT USER_ID
FROM COMMENTS
)X
I used POSTS and COMMENTS as table names bc I was unsure what your exact table names are, so make sure to change these in your query.
This should work:
SELECT COUNT(DISTINCT USER_ID) FROM (
SELECT USER_ID FROM POST_TABLE
UNION
SELECT USER_ID FROM COMMENT_TABLE
)
id(pk) user_id(int) came_to_site(date_time) purchases(int)
1 1 27-8-2016:10:12:23 0
2 2 27-8-2016:10:20:23 0
3 1 28-8-2016:10:12:23 1
4 3 29-8-2016:10:12:23 0
5 4 29-8-2016:11:40:23 0
6 4 30-8-2016:10:12:23 0
7 4 30-8-2016:12:12:23 1
8 1 30-8-2016:12:30:23 1
I have this table, I want to know, on average, how many times a user came before making first purchase.
We can ignore user 2 and 3 because they never made a purchase.
User 1 came 2 times before making a purchase.
User 4 came 3 times before making a purchase.
So average would be (2 + 3)/2 = 2.5
Any idea how can I write such a query?
select avg(cnt)
from
(
select user_id, 1 + count(*) as cnt
from tablename t1
where purchases = 0
and exists (select 1 from tablename t2
where t2.user_id = t1.user_id
and t2.purchases = 1)
and not exists (select 1 from tablename t3
where t3.user_id = t1.user_id
and t3.purchases = 1
and t3.came_to_site < t1.came_to_site)
group by user_id
)
The sub-query counts each user_id that has made a purchase (EXISTS), but not before current row (NOT EXISTS).
At main level, do AVG() to get average number.
Perhaps, depending on dbms, you need to do avg(cnt * 1.0) to avoid integer result.
Find the first purchase date of all users that made a purchase, then join to that:
select avg(visits)
from (select t.user_id, count(*) visits
from (select user_id, min(came_to_site) first
from mytable
where purchases > 0
group by user_id) fpd
join mytable t on t.user_id = fpd.user_id and t.came_to_site < fpd.came_to_site) x
With an index on user_id this will perform pretty well.
You could do :
SELECT AVG(cpt) FROM (
SELECT sales_user.user_id, COUNT(*) AS cpt
FROM (
SELECT *
FROM users
WHERE purchases=1) sales_user
JOIN users ON sales_user.user_id=users.user_id
WHERE users.came_to_site < sales_user.came_to_site
GROUP BY sales_user.user_id);
I have a table where I can store the same name with different states.
|ID|name|state
1 A 1
2 A 2
3 B 3
4 C 1
There 3 states 1,2,3.
How can I find those records which has no state 3, maximum 2?
In this example A and C has no state 3 so they would be the result of the query:
SELECT * FROM `records` WHERE (`state_id`!=3)
It only returns rows without state 3 but it can be that value.
http://www.sqlfiddle.com/#!9/35dbe/2
SELECT r.*
FROM `records` r
LEFT JOIN `records` r3
ON r.name = r3.name
AND r3.state=3
WHERE r3.state IS NULL
How about a DISTINCT and NOT IN?
Something like
SELECT DISTINCT Name
FROM Table1 t
WHERE Name NOT IN (
SELECT Name
FROM Table1 s
WHERE s.State = 3)
SQL Fiddle DEMO
You can do this with conditional aggregation:
select name from t
group by name
having sum(case when state = 3 then 1 else 0 end) = 0
Fiddle http://sqlfiddle.com/#!9/a8bb5/2
I have this row set:
ID player_id team_id created
1 2 1 2011-05-03 19:07:03
2 3 1 2011-05-05 12:13:18
3 2 5 2011-05-07 18:12:54
I would select player that belongs to team_id=1 but from this result i want to remove player_id=2 cause this player actually has moved and he plays in team 5 (no more in team_id=1). So the final result will be:
ID player_id team_id created
2 3 1 2011-05-05 12:13:18
How to write a query to do this? Can I write it in a single query? How?
Regards
Basically you can start by selecting everyone that has ever been a part of a team and then remove anyone who has an entry for another team that was created after their entry for the team in question. This query specifically allows you to change the team_id in only one place and have the correct result if you want to check more than one team.
SELECT
t1.*
FROM
my_table t1
WHERE
t1.team_id = 1
AND
NOT EXISTS(
SELECT
t2.id
FROM
my_table t2
WHERE
t2.player_id = t1.player_id
AND
t2.team_id != t1.team_id
AND
t2.created > t1.created);
A bit like:
SELECT allData.ID, allData.player_Id, allData.team_Id
FROM myTable allData
JOIN
(SELECT
player_id,
MAX(created) AS newestTime
FROM myTable
GROUP BY player_id) mostRecent
ON allData.player_id = mostRecent.player_id
AND allData.created = mostRecent.newestTime
WHERE team_id = 1