Autor Zpráva
jakubk0c
Profil
Dobrý den,

potřeboval bych propojit 2 tabulky. Mám SQL DOTAZ (tabulka.person) do kterého potřebuju dosadit hodnoty z tabulka.ticket.

tabulka.PERSON
id / name / prijezd_id(ticket.id) / odjezd_id(ticket.id) /...


tabulka.TICKET
id / name / prijezd(datum) / odjezd(datum)/...


person.prijezd_id = ticket.prijezd
person.odjezd_id = ticket.odjezd


SELECT den,
       Sum(zmena) zmena
  FROM   (SELECT Greatest(`prijezd_id`, Str_to_date('".$_POST['prijezd']."')) den,
               `count` zmena
        FROM   `person`
        WHERE  `odjezd_id` > Str_to_date('".$_POST['prijezd']."')
               AND `prijezd_id` < Str_to_date('".$_POST[odjezd']."')
        UNION ALL
        SELECT Least(`odjezd_id`, Str_to_date('".$_POST[odjezd']."')) den,
               -`count` zmena
        FROM   `person`
        WHERE `odjezd_id` > Str_to_date('".$_POST['prijezd']."')
               AND `prijezd_id` < Str_to_date('".$_POST[odjezd']."')) d
  GROUP  BY den
  ORDER  BY den  
Kajman
Profil
A tabulka try je co?
jakubk0c
Profil
Kajman:
Moje chyba try = person
Kajman
Profil
Tu strukturu nechápu. Osoba má odkaz na dva tickety jednou nazvaný jako příjezd, jednou jako odjezd a oba každý z těch dvou ticketů má příjezd a odjezd jako datum. Také je divné porovnávat prijezd_id s datumem - ta ukázka opravdu funguje?
jakubk0c
Profil
Zkusím to popsat.
Osoba si udělá rezervaci na pokoj.
Do DB (tabulka.person) se zapíšou data id_room, id.letenky pro příjezd a id.letenky pro odjezd.

Poté tímto algoritmem zkoumám kolik je pokojů obsazených a podle datumu letenky příletové a odeltové zjistim datum kdy je pokoj obsazený.
A v tabulce ticket mám uložený údaje o datumu odletu a datumu přílet.

potřebuju nějak místo `prijezd_id` dosadit datum z tabulky ticket.date_departure.
a místo `odjezd_id` taky dosadit datum z tabulky ticket.date_departure.

V tabulce Person mám uložený id letenky pro odlet a id letenky pro přílet.

V tabulce ticket podle id najdu sloupec date_departure a ten tam chci dosadit. a to samé pro odlet.
Kajman
Profil
Asi něco takového?
SELECT p.*,
       tprij.date_departure prijezd,
       todj.date_arrival    odjezd
FROM `person` p 
LEFT JOIN `ticket` tprij ON p.prijezd_id = tprij.id
LEFT JOIN `ticket` todj  ON p.odjezd_id = tpodj.id
jakubk0c
Profil
Přesně to je ono. Pomohl by jste mi to ještě zakomponovat do toho dotazu? Prosím
Kajman
Profil
Tak si udělejte view a dotaz nechte původní, jen místo původní tabulky berte data z toho view.

Něco jako

CREATE VIEW prijezdy_dle_letenek AS
SELECT p.*,
       tprij.date_departure prijezd,
       todj.date_arrival    odjezd
FROM `person` p 
LEFT JOIN `ticket` tprij ON p.prijezd_id = tprij.id
LEFT JOIN `ticket` todj  ON p.odjezd_id = tpodj.id

Nebo u novějších verzich si to můžete jen pojmenovat lokálně pro dotaz.

WITH prijezdy_dle_letenek as
(
SELECT p.*,
       tprij.date_departure prijezd,
       todj.date_arrival    odjezd
FROM `person` p 
LEFT JOIN `ticket` tprij ON p.prijezd_id = tprij.id
LEFT JOIN `ticket` todj  ON p.odjezd_id = tpodj.id)
SELECT den...

Ale, co když někdo přijde po svých? Když nebude mít letenku s příletem, tak nebude blokovat místo, a když nebude mít letenku pryč, tak ho naopak neuvolní. Přijde mi to divné.
jakubk0c
Profil
Kajman:
To co píšete, to nenastane tadle situace. Je to zadání.
Vždy se vybere letenka tam a letenka zpět.

Jinak používám MySQL 5.7.

To CREATE VIEW to mi nefunguje nebo nevím moc jak na to. Nikdy jsem tendle příkaz napoužíval.

CREATE VIEW prijezdy_dle_letenek AS
SELECT p.*,
       tprij.date_departure prijezd,
       todj.date_arrival    odjezd
FROM `person` p 
LEFT JOIN `ticket` tprij ON p.prijezd_id = tprij.id
LEFT JOIN `ticket` todj  ON p.prijezd_id = tpodj.id

SELECT den,
       Sum(zmena) zmena
  FROM   (SELECT Greatest(`prijezd_id`, Str_to_date('".$_POST['prijezd']."')) den,
               `count` zmena
        FROM   `p`
        WHERE  `odjezd_id` > Str_to_date('".$_POST['prijezd']."')
               AND `prijezd_id` < Str_to_date('".$_POST[odjezd']."')
        UNION ALL
        SELECT Least(`odjezd_id`, Str_to_date('".$_POST[odjezd']."')) den,
               -`count` zmena
        FROM   `p`
        WHERE `odjezd_id` > Str_to_date('".$_POST['prijezd']."')
               AND `prijezd_id` < Str_to_date('".$_POST[odjezd']."')) d
  GROUP  BY den
  ORDER  BY den 
Keeehi
Profil
jakubk0c:
To že splácneš dva nesouvisející dotazy dohromady samozřejmě fungovat nemůže. CREATE VIEW je samostaný příkaz, který pustíš jednou ručně. Vytvoří ti takovou virtuální tabulku. Tudíž pak můžeš psát SELECT * FROM prijezdy_dle_letenek.

Ten dotaz co se pak vykonává změníš tak, že nebere data z tabulky person ale nově z tabulky prijezdy_dle_letenek . To je první možnost.


Druhou možností je, že nebudeš vytvářet separátní virtuální tabulku, ale ten výpočet uděláš přímo v tom dotazu.
SELECT
    den,
    sum(zmena) AS zmena
FROM (
    SELECT
        greatest(`prijezd_id`, str_to_date('".$_POST['prijezd']."')) AS den,
        `count` AS zmena
    FROM (
        SELECT
            p.*,
            tprij.date_departure prijezd,
            todj.date_arrival    odjezd
        FROM
            `person` AS p 
        LEFT JOIN
            `ticket` AS tprij
        ON
            p.prijezd_id = tprij.id
        LEFT JOIN
            `ticket` AS todj
        ON
            p.odjezd_id = tpodj.id
    ) AS `q`
    WHERE
        `odjezd_id` > str_to_date('".$_POST['prijezd']."') AND
        `prijezd_id` < str_to_date('".$_POST['odjezd']."')

    UNION ALL

    SELECT
        least(`odjezd_id`, str_to_date('".$_POST['odjezd']."')) AS den,
        -`count` AS zmena
    FROM (
        SELECT
            p.*,
            tprij.date_departure prijezd,
            todj.date_arrival    odjezd
        FROM
            `person` AS p 
        LEFT JOIN
            `ticket` AS tprij
        ON
            p.prijezd_id = tprij.id
        LEFT JOIN
            `ticket` AS todj
        ON
            p.odjezd_id = tpodj.id
    ) AS `r`
    WHERE
        `odjezd_id` > str_to_date('".$_POST['prijezd']."') AND
        `prijezd_id` < str_to_date('".$_POST['odjezd']."')
) d
GROUP  BY
    den
ORDER  BY
    den 

Ten subdotaz, jak je vidět je ale v query 2x. Takže v novějších verzích se dá předřadit před celý SELECT.
WITH prijezdy_dle_letenek AS (
    SELECT
        p.*,
        tprij.date_departure prijezd,
        todj.date_arrival    odjezd
    FROM
        `person` AS p 
    LEFT JOIN
        `ticket` AS tprij
    ON
        p.prijezd_id = tprij.id
    LEFT JOIN
        `ticket` AS todj
    ON
        p.odjezd_id = tpodj.id
)
SELECT
    den,
    sum(zmena) AS zmena
FROM (
    SELECT
        greatest(`prijezd_id`, str_to_date('".$_POST['prijezd']."')) AS den,
        `count` AS zmena
    FROM
        prijezdy_dle_letenek
    WHERE
        `odjezd_id` > str_to_date('".$_POST['prijezd']."') AND
        `prijezd_id` < str_to_date('".$_POST['odjezd']."')

    UNION ALL

    SELECT
        least(`odjezd_id`, str_to_date('".$_POST['odjezd']."')) AS den,
        -`count` AS zmena
    FROM
        prijezdy_dle_letenek
    WHERE
        `odjezd_id` > str_to_date('".$_POST['prijezd']."') AND
        `prijezd_id` < str_to_date('".$_POST['odjezd']."')
) d
GROUP  BY
    den
ORDER  BY
    den 

Na závěr ještě poznámka, že vkládání neošetřených vstupů do SQL řetězce je bezpečnostní díra - SQL injection. S dotazem to nesouvisí ale je vhodné to alespoň zmínit.
jakubk0c
Profil
Super děkuji, todle pomohlo.

Dotazy ošetřím s tím se počítá.

Děkuju moc

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm:

0