If this is your first visit, be sure to check out the FAQ by clicking the link above. You may have to register before you can post: click the register link above to proceed. To start viewing messages, select the forum that you want to visit from the selection below.

 
Go Back  dBforums > Database Server Software > MySQL > Complex(?) Query Frustration

Reply
 
LinkBack Thread Tools Search this Thread Display Modes
  #1 (permalink)  
Old 04-26-11, 21:23
sjarman sjarman is offline
Registered User
 
Join Date: Jan 2010
Posts: 9
Complex(?) Query Frustration

I'm totally stumped trying to create a query for a MySQL database. Hoping someone might have some hints for me.

Given this example table, I need to be able to find the people (personid) that have the most matches with a provided personid based on two fields - type and name.

For example, if I run the query for personid '1', it would need to return that personid 2 matches once, personid 3 matches twice, and personid 4 matches three times.

In terms of return fields, personid and matchcount is all I need - e.g.

Code:
2,1
3,2
4,3
Does anyone know if it's even possible?

Thanks!


Code:
id	personid	type	name
1	1	1	blue
2	1	2	green
3	1	1	yellow
4	1	1	white
5	2	2	red
6	2	2	green
7	2	3	blue
8	2	1	purple
9	3	1	purple
10	3	1	white
11	3	2	orange
12	3	1	yellow
13	3	2	white
14	4	1	white
15	4	3	grey
16	4	2	green
17	4	1	blue
18	4	2	green
Reply With Quote
  #2 (permalink)  
Old 04-26-11, 21:59
r937 r937 is offline
SQL Consultant
 
Join Date: Apr 2002
Location: Toronto, Canada
Posts: 19,525
please explain how person 2 matches person 1 only once

what is the purpose of the name column?
__________________
r937.com | rudy.ca
please visit Simply SQL and buy my book
Reply With Quote
  #3 (permalink)  
Old 04-26-11, 22:03
sjarman sjarman is offline
Registered User
 
Join Date: Jan 2010
Posts: 9
Person 2 matches on the 2,green combination and nothing else. i.e. persons 1 and 2 have "2,green" in common. Maybe "in common" is a better way to describe what I'm trying to query.
Reply With Quote
  #4 (permalink)  
Old 04-26-11, 22:21
r937 r937 is offline
SQL Consultant
 
Join Date: Apr 2002
Location: Toronto, Canada
Posts: 19,525
Quote:
Originally Posted by sjarman View Post
Person 2 matches on the 2,green combination and nothing else. i.e. persons 1 and 2 have "2,green" in common.
sorry, i still don't see how

start with personid 1, and show how you make this "in common" connection by explaining which rows (using id column) implement it
__________________
r937.com | rudy.ca
please visit Simply SQL and buy my book
Reply With Quote
  #5 (permalink)  
Old 04-26-11, 22:35
sjarman sjarman is offline
Registered User
 
Join Date: Jan 2010
Posts: 9
Sorry - I'm probably explaining it poorly. This image should help:

http://www.nocturnalware.biz/temp/matches.png

You can see the "in common" items for person 2 and person 3, as related to person 1.

So row id 2 (highlighted yellow) and row id 6 (highlighted yellow) are matches because both person 1 and person 2 share the "green" of type "2" combination.

The green highlighted items show how person 1 and person 3 have 2 items in common.
Reply With Quote
  #6 (permalink)  
Old 04-26-11, 23:05
r937 r937 is offline
SQL Consultant
 
Join Date: Apr 2002
Location: Toronto, Canada
Posts: 19,525
okay, i finally understand
Code:
SELECT that.personid
     , COUNT(*) AS matches
  FROM daTable AS this
INNER
  JOIN daTable AS that
    ON that.type = this.type
   AND that.name = this.name
   AND that.personid <> this.personid 
 WHERE this.personid = 1
GROUP
    BY that.personid
note that the match count for 4 should be 4, not 3 (see rows 16 and 18)
__________________
r937.com | rudy.ca
please visit Simply SQL and buy my book
Reply With Quote
  #7 (permalink)  
Old 04-26-11, 23:52
sjarman sjarman is offline
Registered User
 
Join Date: Jan 2010
Posts: 9
Ooo... I'll get to work on that with some real data and see how it goes. Looks good though! Thanks so much!

I've been staring at the problem so long now I don't think I ever would have got there.

And yes, you're right about 4 - I stuffed up that count
Reply With Quote
  #8 (permalink)  
Old 04-27-11, 04:26
mike_bike_kite mike_bike_kite is offline
vaguely human
 
Join Date: Jun 2007
Location: London
Posts: 2,519
Moved thread to MySQL forum
__________________
Mike
Reply With Quote
  #9 (permalink)  
Old 04-27-11, 22:17
sjarman sjarman is offline
Registered User
 
Join Date: Jan 2010
Posts: 9
OK. So that all works perfectly, but I'm struggling with something again...

I'm trying to now pull additional details from my profiles table at the same time. This is what I'm trying, but it's not working at all:

Code:
SELECT that.profileid, COUNT(that.*) AS matches, profiles.name, profiles.age FROM (likes AS this INNER JOIN profiles ON that.profileid = profiles.profileid) INNER JOIN likes AS that ON that.typeidx = this.typeidx AND that.data = this.data AND that.profileid <> this.profileid WHERE this.profileid = 1 GROUP BY that.profileid
Can anyone spot what I'm doing wrong? My skills in this area are pretty limited unfortunately.
Reply With Quote
  #10 (permalink)  
Old 04-27-11, 22:22
sjarman sjarman is offline
Registered User
 
Join Date: Jan 2010
Posts: 9
And then of course, I immediately get it working. Sorry. This seems to be giving me the results I want:

Code:
SELECT that.profileid, COUNT(*) AS matches, profiles.name FROM likes AS this INNER JOIN (likes AS that INNER JOIN profiles ON that.profileid = profiles.profileid) ON that.typeidx = this.typeidx AND that.data = this.data AND that.profileid <> this.profileid WHERE this.profileid = 1 GROUP BY that.profileid
Reply With Quote
  #11 (permalink)  
Old 04-27-11, 22:26
r937 r937 is offline
SQL Consultant
 
Join Date: Apr 2002
Location: Toronto, Canada
Posts: 19,525
two things

first, why would you remove the line breaks? a single line query is a ~real~ bitch to read
Code:
SELECT that.profileid
     , COUNT(that.*) AS matches
     , profiles.name
     , profiles.age 
  FROM (
       likes AS this 
INNER 
  JOIN profiles 
    ON that.profileid = profiles.profileid  -- wrong join condition
       ) 
INNER 
  JOIN likes AS that 
    ON that.typeidx = this.typeidx 
   AND that.data = this.data 
   AND that.profileid <> this.profileid 
 WHERE this.profileid = 1 
GROUP 
    BY that.profileid
second, why would you add parentheses in the FROM clause?

also, the join inside the parentheses will cause a syntax error because the ON clause of that join refers to a table that isn't part of that join

what you want to do is add the join to the profiles table as a subsequent join after the previous one, not in front of it
__________________
r937.com | rudy.ca
please visit Simply SQL and buy my book
Reply With Quote
  #12 (permalink)  
Old 04-27-11, 22:34
sjarman sjarman is offline
Registered User
 
Join Date: Jan 2010
Posts: 9
Sorry - the line breaks were missing because I copied this straight from my PHP code.

All sorted and working though.

Thanks!
Reply With Quote
Reply

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On