sql >> Database >  >> RDS >> Mysql

Geavanceerde (?) EN / OF-query

Ik moet zeggen - ik ben stomverbaasd. Ik kan geen oplossing bedenken die ook maar in de buurt zou komen. Ik zou proberen een oplossing te zoeken in deze richtingen:

  • Door de gebruiker gedefinieerde aggregatiefuncties. Misschien kun je een functie maken die als argument de gewenste uitdrukking (in een vereenvoudigde syntaxis) en de rijen voor een enkele persoon neemt. De functie parseert vervolgens de uitdrukking en vergelijkt deze met de rijen. Hmm... misschien bevat MySQL een aaneengeschakelde aggregaatfunctie en een regex-matchingfunctie? Dit zou dan een oplossing kunnen zijn (hoewel waarschijnlijk niet een erg snelle).
  • Analytische functies. Ik pretendeer niet dat ik ze begrijp, maar voor zover ik over hen weet, denk ik dat ze over het algemeen in deze richting gaan. Hoewel ik niet weet of er een functie zal zijn die aan deze behoefte zal voldoen.

Toegevoegd: Aha, ik denk dat ik het snap! Al denk ik dat de uitvoering ellendig zal zijn. Maar dit gaat lukken! Als u bijvoorbeeld moet zoeken naar 1 AND 2 AND (3 OR 4) dan zou je schrijven:

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)
    )

Toegevoegd 2: Hier is er nog een, hoewel de uitvoering waarschijnlijk nog slechter zal zijn:

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

Toegevoegd 3: Dit is een variant op nr. 2, maar deze heeft misschien wel een kans op een behoorlijke prestatie!

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))

Als je een index toevoegt aan PersonCriteria op kolommen (PersonID,CriteriaID) (precies in deze volgorde!), dan denk ik dat het in ieder geval ongeveer net zo snel gaat als je gaat krijgen.



  1. Waarom is deze SQL-query met subquery erg traag?

  2. Verschil tussen left join en left outer join

  3. PostgreSQL:FOUT:42601:een kolomdefinitielijst is vereist voor functies die record retourneren

  4. Kan MySQL-datum/tijd-waarde niet converteren naar System.DateTime in VS2010