• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

question-closed Złożone zapytanie SQL do 3 tabel z filtrowaniem sortowaniem oraz stronnicowaniem

0 głosów
756 wizyt
pytanie zadane 19 stycznia 2019 w SQL, bazy danych przez Vxid Functixn Bywalec (2,720 p.)
zamknięte 19 stycznia 2019 przez Vxid Functixn

Witam mam kłopot z zapytaniem które pobiera mi listę projektów według określonych reguł.

Zapytanie wygląda tak

SELECT projects.id, projects.name, projects.intro, projects.start_date, projects.priority 
FROM projects 
INNER JOIN join_groups ON join_groups.user_id = 1
INNER JOIN allocations ON allocations.user_id = 1 
WHERE 1 AND (projects.only_group = 0 OR (projects.only_group = join_groups.group_id AND join_groups.user_id = 1)) 
ORDER BY projects.start_date DESC, projects.id 
LIMIT 10 
OFFSET 0

problem polega na tym, że nie bardzo wiem jak połączyć te tabele. Jeśli w dołączonych tabelach znajduje się potencjalnie poprawny wynik to wszystko działa jeśli jednak w dołączonych tabelach nie ma żadnego rekordu nic się nie wyświetla.

Zapytanie jest generowane przez skrypt w php
 

   public function get_project_list($args) {
        $select = '
SELECT projects.id, projects.name, projects.intro, projects.start_date, projects.priority';
        $from = ' 
FROM projects 
INNER JOIN join_groups ON join_groups.user_id = ' . $args['user_id'] . '
INNER JOIN allocations ON allocations.user_id = ' . $args['user_id'];
        
        $where = ' 
WHERE ' . $args["filter"] . ' AND (projects.only_group = 0 OR (projects.only_group = join_groups.group_id AND join_groups.user_id = ' . $args['user_id'] . '))';

        $like = $args["phrase"] != '' ? ' 
AND (projects.name LIKE "%' .$args["phrase"] . '%" OR projects.client LIKE "%' .$args["phrase"] . '%")'
        : '';

        $direction = (int)$args["direction"] == 1 ? ' DESC' : ''; 

        $orderby = ' 
ORDER BY projects.' . $args["sort"] . $direction . ', projects.id';
        
        $offset = ' 
OFFSET ' . $args["offset"];
        $limit = ' 
LIMIT ' . $args["limit"];

        try{
            $query = $this->connect->prepare(
                $select .$from . $where . $like . $orderby . $limit . $offset
            );
            $query->execute();
        } catch(PDOException $error) {
            exit('Błąd łączenia z bazą danych');
        }

Regóły sortowania oraz filtrowania są pobierane z pliku konfiguracyjnego w innym skrypcie i przekazywane do tej funkcji
 

"filter" => [
        "1",
        "projects.end_date IS NULL",
        "projects.end_date IS NOT NULL",
        "projects.priority != 0",
        "projects.settled = 0",
        "projects.id = allocations.project_id AND allocations.user_id = " . $_SESSION["user_id"]
    ],
"sort" => [
        "start_date",
        "end_date",
        "name",
        "priority",
        "type",
        "client"
    ]

Struktura tych 3 tabel wygląda tak:

tabela projects

 

Tabela join_groups

 

Tabela allocations

No i moje pytanie jak to połączyć żeby to działało nawet jak w tych dołączonych tabelach nie ma wpisu z odpowiednim id użytkownika?

komentarz zamknięcia: Znalazłem rozwiązanie jest ono w odpowiedzi.

1 odpowiedź

0 głosów
odpowiedź 19 stycznia 2019 przez Vxid Functixn Bywalec (2,720 p.)
Znalazłem rozwiązanie, INNER JOIN zwraca część wspólną z wszystkich 3 tabel dlatego kiedy wymaganego elementu nie ma w jednej z tabel nic się nie wyświetli. LEFT JOIN zwraca wszystkie rekordy z tabeli po lewej czyli w tym wypadku projects niezależnie czy w dołączanych tabelach są pasujące dane czy też nie. Dlatego rozwiązaniem jest zastosowanie LEFT JOIN zamiast INNER JOIN.

Podobne pytania

0 głosów
1 odpowiedź 756 wizyt
pytanie zadane 24 grudnia 2019 w SQL, bazy danych przez chmieluziomal Początkujący (450 p.)
0 głosów
1 odpowiedź 258 wizyt
pytanie zadane 16 stycznia 2018 w SQL, bazy danych przez ThreeG Nowicjusz (170 p.)
0 głosów
1 odpowiedź 290 wizyt
pytanie zadane 11 października 2015 w SQL, bazy danych przez Dawid Warduliński Obywatel (1,830 p.)

93,664 zapytań

142,580 odpowiedzi

323,121 komentarzy

63,189 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj

Twierdza Linux. Bezpieczeństwo dla dociekliwych

Aby uzyskać rabat -10%, użyjcie kodu pasja-linux, wpisując go w specjalne pole w koszyku.

...