My tables are:
frequents(bar,drinker);
likes(beer,drinker);
serves(bar,beer)
I want to "select pairs of drinkers who frequents exactly the same bars".I think I can write that query using only the frequents table (as it has both bar and drinker column) using self joints I tried to do but couldn't get it.I don't mind using other tables too to get the exact query.The query must select drinkers who goes to the same bars only.In other words they should have all the the bars in common.The query must be in generalized form it should not depend on data that's why I didn't put any data.
DRINKER | BAR
____________________
John | Hyatt
Smith | Blue
William | Hilton
John | Geoffreys
Smith | Hyatt
Joe | Blue
Mike | Hilton
William | Dublin
Jeff | Hilton
Jake | Hilton
This is my frequents table I need to select only Joe and Smith and also Jake and Jeff because they visit exactly the same bars.
THe easiest way in MySQL is to use group_concat()
to put the values together and compare:
select fd.bars, group_concat(fd.drinker) as drinkers
from (select f.drinker, group_concat(f.bar order by f.bar) as bars
from frequents f
group by f.drinker
) fd
group by bars
having count(*) > 1;
EDIT
You can also do this using join
s, but to do it right, you need a full outer join
-- which MySQL does not support.
Another way is to count the number of bars that each goes to, do an inner join, and be sure that the counts match as well as the bars:
select f1.drinker, f2.drinker
from frequents f1 join
frequents f2
on f1.bar = f2.bar join
(select f.drinker, count(*) as numbars
from frequents f
group by f.drinker
) fd1
on f1.drinker = fd1.numbars join
(select f.drinker, count(*) as numbars
from frequents f
group by f.drinker
) fd2
on f2.drinker = f2.drinker
group by f1.drinker, f2.drinker
having count(*) = max(f1.numbars) and count(*) = max(f2.numbars);
This may help, however I'm using my knowledge from Microsoft SQL server. The syntax may differ from MYSQL. That being said you would need to JOIN the tables into themselves.
SELECT F.Bars, F.Drinkers, FB.Drinker
FROM frequents F
JOIN frequents FB ON (FB.Drinkers = F.Bars)
WHERE FB.Drinkers = F.Drinkers
basically I join the same table to itself saying the FB.Drinkers contains the bars that drinkers go to and F.Drinkers is the list of people who drink. I'm not 100% on the syntax but the idea is correct.
I haven't done SQL in 4 months. if you don't use it, you loose it :)
fixnode's answer is pretty good, although it lacks 2 little details that I think are important, select only non repeated results and sort them in a useful way.
SELECT DISTINCT tbl_1.drinker, tbl_1.bar
FROM `frequents` AS tbl_1
LEFT JOIN frequents AS tbl_2 ON tbl_1.bar = tbl_2.bar WHERE tbl_1.bar = tbl_2.bar
ORDER BY tbl_1.bar;
This is what I used for testing
CREATE TABLE IF NOT EXISTS `frequents` (
`bar` varchar(100) NOT NULL,
`drinker` varchar(100) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `frequents` (`bar`, `drinker`) VALUES
('bar_1', 'drinker_3'),
('bar_2', 'drinker_3'),
('bar_3', 'drinker_4'),
('bar_4', 'drinker_1'),
('bar_5', 'drinker_1'),
('bar_1', 'drinker_5'),
('bar_2', 'drinker_4'),
('bar_3', 'drinker_3'),
('bar_4', 'drinker_2'),
('bar_5', 'drinker_1');
Well you are not showing anyone desired output but if you add a table for the bar, then this will work for you
select f.bar, f.drinker from frequents f
inner join bar b on b.bar = f.bar
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.