Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Zaawansowane (?) zapytanie AND / OR

Muszę powiedzieć - jestem zakłopotany. Nie potrafię wymyślić żadnego rozwiązania, które byłoby nawet bliskie. Spróbowałbym poszukać rozwiązania w tych kierunkach:

  • Funkcje agregujące zdefiniowane przez użytkownika. Może możesz stworzyć funkcję, która jako argument przyjmuje żądane wyrażenie (w uproszczonej składni) i wiersze dla jednej osoby. Następnie funkcja analizuje wyrażenie i dopasowuje je do wierszy. Hmm... może MySQL zawiera jakąś konkatenującą funkcję agregującą i funkcję dopasowującą regex? To może być rozwiązanie (choć prawdopodobnie niezbyt szybkie).
  • Funkcje analityczne. Nie udaję, że je rozumiem, ale o ile wiem o nich, to myślę, że generalnie zmierzają w tym kierunku. Chociaż nie wiem, czy będzie funkcja, która zaspokoi tę potrzebę.

Dodano: Ach, myślę, że to rozumiem! Chociaż myślę, że występ będzie marny. Ale to zadziała! Na przykład, jeśli musisz wyszukać 1 AND 2 AND (3 OR 4) wtedy napisałbyś:

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

Dodano 2: Oto kolejny, choć wydajność prawdopodobnie będzie jeszcze gorsza:

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

Dodano 3: Jest to odmiana nr 2, ale w rzeczywistości może mieć szansę na przyzwoitą wydajność!

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

Jeśli dodasz indeks do PersonCriteria w kolumnach (PersonID,CriteriaID) (dokładnie w tej kolejności!), to myślę, że jest to mniej więcej tak szybko, jak to możliwe.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Pobierz datę i przekonwertuj ją na określoną strefę czasową zgodnie ze strefą czasową użytkownika

  2. Jak łączyć ciągi w MySQL za pomocą CONCAT()

  3. Jak usunąć wiodące i końcowe znaki w MySQL?

  4. Pobierz z bazy danych, ale tylko przez 30 dni

  5. PHP MySql (1045) Odmowa dostępu dla użytkownika