简体   繁体   中英

How to compare rows of the same table and apply a weight from another table to each column

I am trying to build a sort of 'personals' matching database in MySQL.

  • I need to compare a specific person in the Members table to all of the others in the same table.

  • Each row (person) in the table has a number of columns with their info (age, location, religion, etc).

  • I need the query to reference a table that holds my 'weights' for each column. In other words, I want to say "location is important at 75, age-range is super important at 100, and religion is not important at 10".

Members Table

+----+-------+----------+----------+-----+----------+
| ID | Name  | Location | Religion | Age | AgeRange |
+----+-------+----------+----------+-----+----------+
| 1  | Joe   | LA       | Athiest  | 40  | 30-40    |
+----+-------+----------+----------+-----+----------+
| 2  | Mary  | LA       | Agnostic | 35  | 35-45    |
+----+-------+----------+----------+-----+----------+
| 3  | Karen | NYC      | Athiest  | 45  | 30-35    |
+----+-------+----------+----------+-----+----------+
| 4  | Lisa  | LA       | Hindu    | 30  | 45-55    |
+----+-------+----------+----------+-----+----------+

Weights Table (how important a parameter is)

+----+-----+----------+----------+
| ID | Age | Location | Religion |
+----+-----+----------+----------+
| 1  | 100 | 75       | 10       |
+----+-----+----------+----------+

I have tried many things over the past 2 days but the latest query I was trying to play with was this, which obviously is not of huge use. It also doesn't specify the 'person' to whom these records would be compared.

SELECT  a.first_name,
        g.name, 
        a.age* g.age+
        a.location* g.location+
        a.religion * g.mwReligion AS metric
    FROM members a, weight g  
    ORDER BY metric DESC;

My intended output would be like this:

Joe Matches:

Mary - Score = 285
(100 because she's in his AgeRange + 100 because he is in her AgeRange + 75 for Location + 10 for religion)

Lisa - Score = 175 (100 because she is in his AgeRange + 75 for location)

Karen - Score = 10 (Only religion matches)

I would assume the min_age and max_age columns are separate (instead of AgeRange ), inclusive, and of INT data type. The query you need should look like:

select 
  x.id,
  x.name,
  x.ma as match_age,
  x.ml as match_location,
  x.mr as match_religion,
  x.ma * w.age + x.ml * w.location + x.mr * w.religion as total_score
from (
  select
    o.id,
    o.name,
    case when o.age between p.min_age and p.max_age then 1 else 0 end as ma,
    case when o.location = p.location then 1 else 0 end as ml,
    case when o.religion = p.religion then 1 else 0 end as mr
  from (select * from members where id = 1) p -- selects Joe
  cross join (select * from members where id <> 1) o -- select other members
) x
cross join weights w

In MySQL Boolean expression become 0 or 1 in numeric context. So you can use your comparisons as factor.

So self join the members on the id of the one being lower than the others (otherwise, ie when just checking for inequality, you had each pair twice in the result). Then cross join the weights.

Now you can build your metric as sum of the multiplications of the comparisons and the weights.

I assume religion and comparison are compared by equality. The age of one person is compared to the age range of the other and the same vice versa. Further more I take the age range as splited into a lower and an upper bound and assume that the range's bounds are inclusive. Then this could look like the following:

SELECT m1.name,
       m2.name,
       (m1.age BETWEEN m2.agerangelower
                       AND m2.agerangeupper) * w1.age
       +
       (m2.age BETWEEN m1.agerangelower
                       AND m1.agerangeupper) * w1.age
       +
       (m1.location = m2.location) * w1.location
       +
       (m1.religion = m2.religion) * w1.religion metric
       FROM members m1
            INNER JOIN members m2
                       ON m1.id < m2.id
            CROSS JOIN weights w1;

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM