nested query v nette database table

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
majo1
Člen | 103
+
0
-

zdravim, mam este jednu dilemu – ako spravit subquery v nette table.

potrebujem tento dotaz

$this->database->table('reservations')->where('skibus_idskibus = ? AND confirmed = 0', $value)->count('idreservation');

vnorit do tohoto dotazu

return $this->database
            ->table('skibuses')
            ->select("idskibus, capacity, CONCAT(DATE_FORMAT(departureDatetime,?), ? , ?) AS departureDatetime, status, centers_idcenter", '%e.%c.%Y (%W)', ' - voľných miest ' , $countResNumInSkibusSel)
            ->order(self::SKIBUSCOLUMN_ID . ' DESC')
            ->where('centers_idcenter = ? AND status = 2', $value);

viete poradit prosim, ako na to?
dakujem

Editoval majo1 (17. 2. 2016 23:20)

majo1
Člen | 103
+
0
-

toto je moj zufaly pokus, ktory nefunguje :)

return $this->database->query('SELECT idskibus, capacity, CONCAT(DATE_FORMAT(departureDatetime,?), ? , (SELECT * FROM reservations WHERE skibus_idskibus = ? AND confirmed = 0)) AS departureDatetime, status, centers_idcenter FROM skibuses WHERE centers_idcenter = ? AND status = 2' , '%e.%c.%Y (%W)', ' - voľných miest ' , $value , $value);
GEpic
Člen | 566
+
0
-

Co přesně chceš dosáhnout? Ukaž jaký výsledek vlastně požaduješ a jaká je struktura tabulek / relací, třeba pomůžu, ale jak tak na to koukám, nevím, co vlastně chceš. :)

majo1
Člen | 103
+
0
-

no, moj aktualny pokus

return $this->database
            ->table('skibuses')
            //->select("idskibus, capacity, DATE_FORMAT(departureDatetime,?) AS departureDatetime, status, centers_idcenter", '%e.%c.%Y (%W)')
            ->select("idskibus, capacity, CONCAT(DATE_FORMAT(departureDatetime,?), ?, (SELECT SUM (numAdult) FROM reservations WHERE skibus_idskibus = ? AND confirmed = 0)) AS departureDatetime, status, centers_idcenter", '%e.%c.%Y (%W)', ' - voľných (zaplnenych) miest ', $value)
            ->order(self::SKIBUSCOLUMN_ID . ' DESC')
            ->where('centers_idcenter = ? AND status = 2', $value);
  • ide mi o to, ze z tabulky skibuses selectujem datum pomocou where do selectboxu (departureDatetimeime)
  • do departureDatetime sa snazim pripojit k datumu sucet stlpcov numAdult, numJunior, numKid a numTransportOnly z tabulky reservations, pre konkretny riadok

a uz mam v tom trochu zmatok :)

Editoval majo1 (17. 2. 2016 23:41)

GEpic
Člen | 566
+
0
-

majo1 napsal(a):

no, moj aktualny pokus

return $this->database
            ->table('skibuses')
            //->select("idskibus, capacity, DATE_FORMAT(departureDatetime,?) AS departureDatetime, status, centers_idcenter", '%e.%c.%Y (%W)')
            ->select("idskibus, capacity, CONCAT(DATE_FORMAT(departureDatetime,?), ?, (SELECT SUM (numAdult) FROM reservations WHERE skibus_idskibus = ? AND confirmed = 0)) AS departureDatetime, status, centers_idcenter", '%e.%c.%Y (%W)', ' - voľných (zaplnenych) miest ', $value)
            ->order(self::SKIBUSCOLUMN_ID . ' DESC')
            ->where('centers_idcenter = ? AND status = 2', $value);
  • ide mi o to, ze z tabulky skibuses selectujem datum pomocou where do selectboxu (departureDatetimeime)
  • do departureDatetime sa snazim pripojit k datumu sucet stlpcov numAdult, numJunior, numKid a numTransportOnly z tabulky reservations, pre konkretny riadok

a uz mam v tom trochu zmatok :)

Já mám jedno pravidlo a sice pokud nejde z databáze něco dostat jednoduše, je špatně navržená. :)
Pak se zbytečně vymýšlej bejkárny. Většina lidí píše databázi až když začne programovat, a je to trošku chyba (neříkám, že ty – potřeboval sem se vylejt :D ).

Editoval GEpic (18. 2. 2016 0:00)

majo1
Člen | 103
+
0
-

Mala by byt dobre navrhnuta :)
Myslim, ze cely ten prikaz funguje, problem nastava pri sum – to v mojom „pokuse“ ani nie je dorobene, kedze neviem, aky postup zvolit, aby som v subquery scital tie 4 stlpce..

majo1
Člen | 103
+
0
-

prosím, poraďte niekto, neviem ako na to :/

ide o to, že každý skibus, ktorý sa ťahá do select boxu má svoju kapacitu. Ja by som rád spočítal obsadenosť (pocet idreservation v reservations ktore maju priradene pozadovane skibus_idskibus) pre konkrétny skibus a vpísal do CONCAT:

public function getSkibusSel($value)
{
    $this->database->query("SET lc_time_names = 'sk_SK'");

    return $this->database
                ->table('skibuses')
                ->select("  idskibus,
                            capacity,
                            CONCAT(DATE_FORMAT(departureDatetime,?), ?, 'X', ? , capacity) AS departureDatetime,
                            status,
                            centers_idcenter"
                                        , '%e.%c.%Y (%W)', ' obsadenosť ', ' z ')
                ->order(self::SKIBUSCOLUMN_ID . ' DESC')
                ->where('centers_idcenter = ? AND status = 2', $value);
}

miesto ‚X‘ by som chcel dosadiť súčet selectnutých stĺpcov numAdult, numJunior, numKid, numTransportOnly z tabuľky reservations

Ďakujem

Editoval majo1 (19. 2. 2016 13:45)

CZechBoY
Člen | 3608
+
0
-

Nemůžeš tam prostě napsat numAdult + numJunior + numKid?

majo1
Člen | 103
+
0
-

CZechBoY napsal(a):

Nemůžeš tam prostě napsat numAdult + numJunior + numKid?

numAdult, numJunior, numKid, numTransportOnly patria do tabulky reservations a nie do tabulky skibuses

CREATE TABLE IF NOT EXISTS `nitransform`.`centers` (
  `idcenter` INT NOT NULL AUTO_INCREMENT,
  `centerName` VARCHAR(45) NULL,
  PRIMARY KEY (`idcenter`))
ENGINE = InnoDB;

CREATE TABLE IF NOT EXISTS `nitransform`.`skibuses` (
  `idskibus` INT NOT NULL AUTO_INCREMENT,
  `capacity` INT NULL,
  `departureDatetime` DATETIME NULL,
  `status` TINYINT(1) NULL,
  `centers_idcenter` INT NOT NULL,
  PRIMARY KEY (`idskibus`, `centers_idcenter`),
  INDEX `fk_skibuses_centers1_idx` (`centers_idcenter` ASC),
  CONSTRAINT `fk_skibuses_centers1`
    FOREIGN KEY (`centers_idcenter`)
    REFERENCES `nitransform`.`centers` (`idcenter`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB;

CREATE TABLE IF NOT EXISTS `nitransform`.`reservations` (
  `idreservation` INT NOT NULL AUTO_INCREMENT,
  `datetime` DATETIME NULL,
  `numAdult` TINYINT NULL,
  `numJunior` TINYINT NULL,
  `numKid` TINYINT NULL,
  `numTransportOnly` TINYINT NULL,
  `confirmed` TINYINT(1) NULL,
  `variable` INT NULL,
  `paid` TINYINT(1) NULL,
  `customer_idcustomer` INT NOT NULL,
  `skibus_idskibus` INT NOT NULL,
  `station_idstation` INT NOT NULL,
  `center_idcenter` INT NOT NULL,
  PRIMARY KEY (`idreservation`, `customer_idcustomer`, `skibus_idskibus`, `station_idstation`, `center_idcenter`),
  INDEX `fk_reservation_customer1_idx` (`customer_idcustomer` ASC),
  INDEX `fk_reservation_skibus1_idx` (`skibus_idskibus` ASC),
  INDEX `fk_reservation_station1_idx` (`station_idstation` ASC),
  INDEX `fk_reservation_center1_idx` (`center_idcenter` ASC),
  CONSTRAINT `fk_reservation_customer1`
    FOREIGN KEY (`customer_idcustomer`)
    REFERENCES `nitransform`.`customers` (`idcustomer`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION,
  CONSTRAINT `fk_reservation_skibus1`
    FOREIGN KEY (`skibus_idskibus`)
    REFERENCES `nitransform`.`skibuses` (`idskibus`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION,
  CONSTRAINT `fk_reservation_station1`
    FOREIGN KEY (`station_idstation`)
    REFERENCES `nitransform`.`stations` (`idstation`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION,
  CONSTRAINT `fk_reservation_center1`
    FOREIGN KEY (`center_idcenter`)
    REFERENCES `nitransform`.`centers` (`idcenter`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)
ENGINE = InnoDB;
majo1
Člen | 103
+
0
-

konečne som sa pohol ďalej :)

public function getSkibusSel($value)
{
    $this->database->query("SET lc_time_names = 'sk_SK'");

    return $this->database
                ->table('skibuses')
                //->select("idskibus, capacity, DATE_FORMAT(departureDatetime,?) AS departureDatetime, status, centers_idcenter", '%e.%c.%Y (%W)')
                ->select("  idskibus,
                            CONCAT(DATE_FORMAT(departureDatetime,?), ?, (SELECT SUM(numAdult + numJunior + numKid + numTransportOnly) FROM reservations WHERE skibus_idskibus = ?), ? , capacity) AS departureDatetime,
                            status,
                            centers_idcenter"
                                        , '%e.%c.%Y (%W)', ' obsadenosť ', $sub , ' z ')
                ->order(self::SKIBUSCOLUMN_ID . ' DESC')
                ->where('centers_idcenter = ? AND status = 2', $value);
}

teraz by to aj fungovalo, len potrebujem v SUBSELECTe za otaznik ($sub) dosadit ID, ktore je prave v nadradenom selecte :D
vôbec netuším, ako sa to rieši

Editoval majo1 (19. 2. 2016 16:03)

CZechBoY
Člen | 3608
+
0
-

Místo otazníku tam dáš prostě ten sloupec.

majo1
Člen | 103
+
0
-

ano, skusal som, aj som to tak nechal. najskor to vyzeralo tak, ze to robi select spravne,
no do selectboxu mi hadzalo aj prazdne hodnoty (vid. obr. nizsie), nedari sa mi to vsak vydumpovat, pravdepod. kvoli zavislym select boxom cez ajax.

momentalne query vyzera takto

public function getSkibusSel($value)
{
    $this->database->query("SET lc_time_names = 'sk_SK'");
    $query = $this->database
                ->table('skibuses')
                //->select("idskibus, capacity, DATE_FORMAT(departureDatetime,?) AS departureDatetime, status, centers_idcenter", '%e.%c.%Y (%W)')
                ->select("  idskibus,
                            CONCAT(DATE_FORMAT(departureDatetime,?), ?, (SELECT SUM(numAdult + numJunior + numKid + numTransportOnly) FROM reservations WHERE skibus_idskibus = idskibus AND confirmed = 1), ? , capacity) AS departureDatetime,
                            status,
                            centers_idcenter"
                                        , '%e.%c.%Y (%W)', ' obsadenosť ' , ' z ')
                ->order(self::SKIBUSCOLUMN_ID . ' DESC')
                ->where('centers_idcenter = ? AND status = 2', $value);
    return $query;
}

a select box sa tvari takto: http://r88i.imgup.net/Beznzvuabad.jpg
a po pridani „AND confirmed = 1“ su vsetky poliaprazdne.
dakujem

Editoval majo1 (19. 2. 2016 23:34)

premek_k
Člen | 172
+
+1
-

Co nějak takhle? Píšu z hlavy, vyzkoušej a případně si to uprav …

<?php
	$query = 'SELECT
				s.idskibus,
				s.departureDatetime,
				s.capacity,
				(SELECT SUM(r.numAdult + r.numJunior + r.numKid + r.numTransportOnly) FROM reservations r WHERE r.skibus_idskibus = s.idskibus AND r.confirmed = 1) AS occupancy,
				s.status,
				c.idcenter
			FROM
				skibuses s,
				centers c
			WHERE
				s.centers_idcenter = c.idcenter AND
				c.idcenter = ? AND
				s.status = 2
			ORDER BY
				s.idskibus DESC';

	return $this->database->query($query, $value);
?>

EDIT:

Případně ještě ošetřit ten SUM, když vrátí NULL – asi nějak takto by to mělo jít:

<?php

COALESCE((SELECT SUM(r.numAdult + r.numJunior + r.numKid + r.numTransportOnly) FROM reservations r WHERE r.skibus_idskibus = s.idskibus AND r.confirmed = 1), 0) AS occupancy,

?>

Editoval premek_k (20. 2. 2016 12:31)

majo1
Člen | 103
+
0
-

velka vdaka @premek_k , prave COALESCE mi chybalo pouzit. Teraz query funguje, ako ma