sql >> Database teknologi >  >> RDS >> Mysql

Avanceret (?) OG/ELLER forespørgsel

Jeg må sige - jeg er lamslået. Jeg kan ikke komme i tanke om nogen løsning, der ville komme i nærheden af. Jeg ville prøve at finde en løsning i disse retninger:

  • Brugerdefinerede aggregerede funktioner. Måske kan du lave en funktion, der tager det ønskede udtryk (i en forenklet syntaks) og rækkerne for en enkelt person som argument. Funktionen analyserer derefter udtrykket og matcher det mod rækkerne. Hmm... måske indeholder MySQL en eller anden sammenkædende aggregeret funktion og en regex matchende funktion? Dette kan da være en løsning (selv om det nok ikke er særlig hurtig).
  • Analytiske funktioner. Jeg foregiver ikke, at jeg forstår dem, men så meget som jeg ved om dem, tror jeg, at de generelt er i denne retning. Selvom jeg ikke ved, om der vil være en funktion, der passer til dette behov.

Tilføjet: Ahh, jeg tror jeg fik det! Selvom jeg tror, ​​at præstationen bliver elendig. Men det her vil virke! For eksempel, hvis du har kravet om at søge efter 1 AND 2 AND (3 OR 4) så ville du skrive:

SELECT
    *
FROM
    Persons A
WHERE
    EXISTS (Select * from PersonCriteria B WHERE A.PersonID=B.PersonID AND CriteriaID=1)
    AND
    EXISTS (Select * from PersonCriteria B WHERE A.PersonID=B.PersonID AND CriteriaID=2)
    AND
    (
        EXISTS (Select * from PersonCriteria B WHERE A.PersonID=B.PersonID AND CriteriaID=3)
        OR
        EXISTS (Select * from PersonCriteria B WHERE A.PersonID=B.PersonID AND CriteriaID=4)
    )

Tilføjet 2: Her er endnu en, selvom ydeevnen sandsynligvis vil være endnu værre:

SELECT p.* FROM Person p
    JOIN (select PersonID from PersonCriteria WHERE CriteriaID=1) c1 ON p.PersonID=c1.PersonID
    JOIN (select PersonID from PersonCriteria WHERE CriteriaID=2) c2 ON p.PersonID=c2.PersonID
    JOIN (select PersonID from PersonCriteria WHERE CriteriaID IN (3,4)) c3 ON p.PersonID=c3.PersonID

Tilføjet 3: Dette er en variation af nr. 2, men det kan faktisk have en chance for en anstændig præstation!

SELECT p.* FROM
    Person p
    JOIN PersonCriteria c1 on (p.PersonID=c1.PersonID AND c1.CriteriaID=1)
    JOIN PersonCriteria c2 on (p.PersonID=c2.PersonID AND c2.CriteriaID=2)
    JOIN PersonCriteria c3 on (p.PersonID=c3.PersonID AND c3.CriteriaID IN (3,4))

Hvis du tilføjer et indeks til PersonCriteria på kolonner (PersonID,CriteriaID) (præcis i denne rækkefølge!), så tror jeg, det er nogenlunde lige så hurtigt, som du kommer til at komme under alle omstændigheder.



  1. Udløser udløser ved opdatering af kolonne A eller KolonneB eller KolonneC

  2. Opdatering af kolonne baseret på eksisterende felter

  3. Kalder Oracle lagret procedure med output parameter fra SQL Server

  4. Har nogen fundet ud af, at REGEX \b ikke virker i MYSQL?