Datensätze geordnet nach Anzahl übereinstimmender Beziehungen

  • Jetzt anmelden. Es dauert nur 2 Minuten und ist kostenlos!

scbawik

Senior HTML'ler
14 Juli 2011
2.552
448
83
Hallo!

Ich habe ein Schema mit vielen Beziehungen:

Code:
Project >-< ProjectTask >---------< Task
Project >-< ProjectTask >---------< Employee
Project >-< ProjectAttribute >----< Attribute
Project >-< ProjectAttribute >----< AttributeValue
Project >-- Address

Insgesamt sind bei einem Projekt inkl. den Subbeziehungen ca 15 Tabellen involviert.

Ich muss jetzt anhand eines gegebenen Entitys, die vier ähnlichsten finden.
Die "Ähnlichkeit" ist Anhand der übereinstimmenden Werte in Fremdtabellen auszumachen.

Wenn also bspw. der Attribut-Typ wie auch der Attribut-Wert zweier Projekte übereinstimmt, steigt die Ähnlichkeit.

Hat jemand einen Denkanstoß für mich?
 
Zuletzt bearbeitet:

scbawik

Senior HTML'ler
14 Juli 2011
2.552
448
83
Hallo!

Ich habe ein Schema mit vielen Beziehungen:

Code:
Project >-< ProjectTask >---------< Task
Project >-< ProjectTask >---------< Employee
Project >-< ProjectAttribute >----< Attribute
Project >-< ProjectAttribute >----< AttributeValue
Project >-- Address

Insgesamt sind bei einem Projekt inkl. den Subbeziehungen ca 15 Tabellen involviert.

Ich muss jetzt anhand eines gegebenen Entitys, die vier ähnlichsten finden.
Die "Ähnlichkeit" ist Anhand der übereinstimmenden Werte in Fremdtabellen auszumachen.

Wenn also bspw. der Attribut-Typ wie auch der Attribut-Wert zweier Projekte übereinstimmt, steigt die Ähnlichkeit.

Hat jemand einen Denkanstoß für mich?

Ok, ich glaube ich habs:

Code:
SELECT
   sp.*,
   ((
       SELECT COUNT(spa.id) FROM project_attribute AS spa WHERE spa.project = sp.id AND spa.attribute = pa.attribute AND spa.attribute_value = pa.attribute_value
   ) * 1)
   +
   ((
       SELECT COUNT(spt.id) FROM project_task AS spt WHERE spt.project = sp.id AND spt.address = pt.address
   ) * .25)
   +
   ((
       SELECT COUNT(spc.id) FROM project_campaign AS spc WHERE spc.project = sp.id AND spc.campaign = pc.campaign
   ) * 2)
   AS similarity
FROM project AS p
LEFT JOIN project_attribute AS pa ON (p.id = pa.project)
LEFT JOIN project_task AS pt ON (p.id = pt.project)
LEFT JOIN project_campaign AS pc ON (p.id = pc.project)
LEFT JOIN project AS sp ON (p.id != sp.id)
WHERE
   p.id = <PROJECT-ID>
GROUP BY sp.id
ORDER BY
   similarity DESC

Habe noch jeweils Multiplikatoren eingebaut, um den Impact nach Typ der "Ähnlichkeit" zu steuern.
Optimierungsvorschläge (ja, wildcard weglassen ist mir klar) nehme ich gerne entgegen, derzeit dauert das ganze ~200ms bei 235 Projekten.