Gå til innhold

[Løst] [PHP, PDO, MySQL] query for å velge 3 tabeller med samme id


Anbefalte innlegg

Hei, jeg trenger litt hjelp nå.

 

Jeg har en litt stor database hvor det kan oppstå tilfeller jeg trenger å bruke en query med3 tabeller i fokus. (Dette blir bestemt med if elseif setninger.)

Det jeg lurer på er hvordan det blir om jeg skal bruke PDO for tilkobling av databasen, jeg vet ikke om selve queryen blir forandret, men hva med uthentingen av data?

 

 

Også lat oss si at vi har disse tre tabellene:

- tabell

- tabell_1

- tabell_2

 

Hvor tabell har feltet id, og tabell_1 og tabell_2 har feltet felt_id. Disse tre feltene skal vere like i queryen. Og id'en skal være definert i en variabel, hvordan ville dere ha gjort det? Jeg forstår ikke helt join funksjonen enda og skulle gjerne hatt hjelp. (alt skal hentes ut *)

 

 

Eksempell med AND (vet dette ikke fungerer):

mysql_query("SELECT * FROM tabell,tabell_1,tabell_2 WHERE 'tabell_1.felt_id'='tabell_2.felt_id' AND 'tabell_1.tabell_id'='tabell.id' AND 'tabell.id'='$ID'");

 

 

 

 

 

Mvh

Fylling - Takker meget for hjelp!

Lenke til kommentar
Videoannonse
Annonse

SELECT *
FROM tabell1
NATURAL JOIN tabell2
NATURAL JOIN tabell3
WHERE tabell1.id = '$id'

 

Dette vil da lage en ny tabell basert på de 3 tidliggere tablenne, hvor de er satt sammen basert på felt med samme navn. Les deg litt opp på hvordan du bruker ulike joins så ser du hvor enkelt det er =)

 

En variant som kanskje er lettere å forstå, men som blir det samme:

SELECT *
FROM tabell1
JOIN tabell2 ON tabell1.id = tabell2.id
JOIN tabell3 ON tabell1.id = tabell3.id
WHERE tabell1.id = '$id'

Endret av etse
Lenke til kommentar

Okey, så jeg må bare passe på å være forsiktig med navnsetting av felta :D

 

Skjønner, ska ta å utdype mej litt mere!

fornuftig navnsetting er alltid bra, men om du har 1 felt i 2 tabeller med samme navn og ikke ønsker at tabellene skal sammenslås på disse så bruk det andre eksempelet jeg viser i forrige post; der velger du selv hvilke felt det skal joines på.
Lenke til kommentar

Med PDO og prepared statement, ett enkelt eksempel. Bør gi ett greit overblikk (håper jeg)

 

<?php

class pdo_ext extends PDO {
protected $_rs;

function __construct() { // utf-8 tilkobling til mysql db
	parent::__construct('mysql:host=localhost;port=3306;dbname=database_navn', 'username', 'password',array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'UTF8'"));	
}

function select_exec($id) {
	$xid=(int)$id;

	$sql="SELECT a.felt1, b.felt2, c.felt3
		FROM tabella a
		INNER JOIN tabellb b ON b.id=a.id
		INNER JOIN tabellc c ON c.id=a.id
		WHERE a.id=:id";

	$this->_rs=$this->prepare($sql);
	$this->_rs->bindValue(':id',$xid,PDO::PARAM_INT); 

	if ($this->rs->execute()) {
		return $this->rs->fetchAll();
	}
}
}

$db=new pdo_ext;
$data=$db->select_exec(1); // id = 1
echo '<pre>';
print_r($data);
echo '</pre>';
?>

Lenke til kommentar

Likte den løsningen din Crowly. Med en slik klasse kan man opprette querys man bruker ofte og få kjapp og fleksibel tilgang til dem :)

 

Personlig har jeg benyttet denne metoden endel ganger:

$id = $_GET['id'];  //  eller annen form...
$sql = '
SELECT tbl1.id AS tbl1Id, tbl1.name AS tbl1Name,
 tbl2.id AS tbl2Id, tbl2.name AS tbl2Name,
 tbl3.id AS tbl3Id, tbl3.name AS tbl3Name,
FROM table_1 tbl1
 JOIN table_2 tbl2 ON tbl2.id = tbl1.tbl2_id  //  sett at table_1 inneholder en kolonne som heter tbl2_id
 JOIN table_3 tbl3 ON tbl3.id = tbl1.tbl3_id  //  sett at table_1 inneholder en kolonne som heter tbl3_id
 WHERE tbl1.id = :id
';
//  echo '<pre>'.var_dump($sql).'</pre>';  //  debug hva som skjer i koden...
$stmt = $dbh->prepare($sql);
$stmt -> bindParam(':id', $id, PDO::PARAM_INT);  //  hvis IDn kun består av tall
$stmt -> execute();
$get = $stmt->fetch(PDO::FETCH_ASSOC);

Ved å benytte deg av AS gir du nytt navn til denne dataen så den ikke kommer i konflikt med andre klonner som deler samme navn i tabellene dine.

Til eksempel har jeg 3 tabeller bestående av postkoder, kommunenavn og fylkenavn. I hver tabell eksisterer "id" og "navn".

Hvis jeg kjører en JOIN på disse, noe jeg ofte gjør, ville jeg navngitt dem på denne måte:

kode.id AS kodeId, kode.navn AS kodeNavn,
komm.id AS kommId, komm.navn AS kommNavn,
fylke.id AS fylkeId, fylke.navn AS fylkeNavn

Nå har jeg full kontroll på hvilke data jeg jobber med.

 

Personlig benytter akkurat denne metoden her: http://dev.thomaskile.me/?page=test-zone&module=PostcodeLookup

Helt umulig å se, men i

> postkode tabellen har jeg; id, navn (poststed), kommune_id, fylke_id

> kommune tabellen har jeg; id, navn (kommune navn), fylke_id

> fylke tabellen har jeg; id, navn (fylke navn)

Endret av Yawa
Lenke til kommentar

AS er ikke nødvendig for å lage ett alias på en tabell eller ett felt, men det gjør det nok litt mer lesbart.

 

Begge disse Select'ene er gyldige

SELECT a.felt1 af1, b.felt1 bf1, c.felt1 cf1 FROM
SELECT a.felt1 AS af1, b.felt1 AS bf1, c.felt1 AS cf1 FROM

 

 

select_exec() funksjonen er langt fra optimal, bl.a. prepare bør/må legges utenom slik at den ikke kjøres for hver nye id. Sql stringen hører heller ikke hjemme der, bør sendes som ett parameter til prepare funksjonen.

Lenke til kommentar

Sant det, men var mest pga. lesligheten jeg tok med AS her samt at jeg personlig bruker det.

Det er snakk om mikroskopiske påvirkninger i hastigheten til PHP, med mindre du er mark zuckerberg :p, så det er vel bare en smakssak...

 

Er ikke så veldi kjent med PDO enda da det ikke er så lenge siden jeg begynte med det selv...

De guidene jeg har lest på har samtlige gitt meg denne fremgangsmåten ved selve spørringen. Det er riktignok på grunnleggende nivå, så at ting kan forenkles og optimaliseres er det ikke tvil om...

 

Har du noen linker hvor jeg kan studere mer rundt dette slik du nevner Crowly...

 

 

EDIT: Mulig jeg tolket siste innlegget ditt noen feil(?)...

Endret av Yawa
Lenke til kommentar

Min egen hjemmesnekrede pdo utvidelse, kan sikkert forbedres, men fungerer. Tips til forbedringer mottas med takk :)

 

 

<?php
class pdo_ext extends PDO {

protected $_err_msg;
protected $_rs;
protected $_bind = array();
public $rader = 0;

/**
 * @param string $ini_fil   Spesifiser path til ini fil med DB oppsett
 * @param bool $utf8    Skal det brukes UTF8 koding mot DB? Std: True
 */
function __construct($inifil='',$utf8 = true) {
	if (empty($inifil)) throw new exception('Ingen ini fil spesifisert');

	$ini=parse_ini_file($inifil, TRUE);
	$dns = $ini['driver'] .
			':host=' . $ini['host'] .
			((!empty($ini['port'])) ? (';port=' . $ini['port']) : '') .
			';dbname=' . $ini['dbname'];

	if ($utf8)
		parent::__construct($dns, $ini['username'], $ini['password'], array(PDO::MYSQL_ATTR_FOUND_ROWS => true, PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'UTF8'"));
	else
		parent::__construct($dns, $ini['username'], $ini['password']);
}

/**
 * @desc    Sjekk om PDO type i Bind er gyldig
 * @param $arr
 * @return bool
 */
protected function _is_pdo_param($arr) {
	/*
	  PDO::PARAM_BOOL (integer)
	  Represents a boolean data type.
	  PDO::PARAM_NULL (integer)
	  Represents the SQL NULL data type.
	  PDO::PARAM_INT (integer)
	  Represents the SQL INTEGER data type.
	  PDO::PARAM_STR (integer)
	  Represents the SQL CHAR, VARCHAR, or other string data type.
	  PDO::PARAM_LOB (integer)
	  Represents the SQL large object data type.
	  PDO::PARAM_STMT (integer)
	  Represents a recordset type. Not currently supported by any drivers.
	  PDO::PARAM_INPUT_OUTPUT (integer)
	  Specifies that the parameter is an INOUT parameter for a stored procedure.
	  You must bitwise-OR this value with an explicit PDO::PARAM_* data type.
	 */
	if (in_array($arr, array(PDO::PARAM_BOOL,
				PDO::PARAM_NULL,
				PDO::PARAM_INT,
				PDO::PARAM_STR,
				PDO::PARAM_LOB,
				PDO::PARAM_STMT,
				PDO::PARAM_INPUT_OUTPUT
					)
			)
	)
		return true;
	else
		return false;
}

/**
 * @desc Hent feilmelding på utført SQL
 * @return bool
 */
public function get_err_msg() {
	if (is_array($this->_err_msg))
		return $this->_err_msg[2];
	else
		return false;
}

/**
 * @desc Fjern feilmelding 
 */
public function reset_err_msg() {
	$this->_err_msg = null;
}

/**
 * @desc Legg til bind verdier
 * @example add_bind(':avis',$this->avis,PARAM_STR)
 * @param string $name Bind navn, eks :avis
 * @param string|int $value  Verdi, eks $avis
 * @param int $type PARAM_BOOL, PARAM_NULL, PARAM_INT, PARAM_STR, PARAM_LOB, PARAM_STMT, PARAM_INPUT_OUTPUT
 * @return bool
 */
public function add_bind($name, $value, $type) {
	if (strlen($name) > 0 and $this->_is_pdo_param($type)) {
		$this->_bind[] = array($name, $value, $type);
		return true;
	}
	else
		return false;
}

/**
 * @desc Fjern alle bind
 */
protected function _reset_bind() {
	$this->_bind = array();
}

/**
 * @desc Kjør bindValue() for alle lagrede binds
 */
protected function _do_bind() {
	if (count($this->_bind) > 0) {
		foreach ($this->_bind as $b)
			$this->_rs->bindValue($b[0], $b[1], $b[2]);
	}
}

/**
 * @desc Forbered SQL for prosessering
 * @param string $sql  SQL settning
 * @throws exception
 * @example parse($sql);
 */
public function parse($sql = '') {
	if (!empty($sql))
		$this->_rs = $this->prepare($sql);
	else
		throw new exception('Parse: Ingen sql spesifisert.');
}

/**
 * @example select_exec()
 * @example select_exec($sql,'a');
 * @example select_exec('','r');
 * @desc Kjør en SELECT spørring
 * @param string $sql
 * @param string $type  a:assoc, r:num, o:objekt (std)
 * @return array|bool
 */
public function select_exec($sql = '', $type = 'o') {
	$this->reset_err_msg();

	if (!empty($sql))
		$this->parse($sql);

	$this->_do_bind();

	if ($this->_rs->execute()) {
		$this->rader = 0;
		switch (mb_strtolower($type)) {
			case 'a':
				while ($row = $this->_rs->fetch(PDO::FETCH_ASSOC)) {
					$data[] = $row;
					$this->rader++;
				}
				break;

			case 'r':
				while ($row = $this->_rs->fetch(PDO::FETCH_NUM)) {
					$data[] = $row;
					$this->rader++;
				}
				break;

			case 'o':
			default:
				while ($row = $this->_rs->fetch(PDO::FETCH_OBJ)) {
					$data[] = $row;
					$this->rader++;
				}
				break;
		}
	} else {
		$data = false;
		$this->_err_msg = $this->_rs->errorInfo();
	}

	$this->_rs->closeCursor();
	$this->_reset_bind();
	if (!isset($data))
		$data = false;

	return $data;
}

/**
 * @desc Kjør en "Ikke SELECT" sql
 * @param string $sql
 * @return bool
 */
public function sql_exec($sql = '') {
	$this->reset_err_msg();

	if (!empty($sql))
		$this->parse($sql);

	$this->rader = 0;
	$this->_do_bind();

	if ($data = $this->_rs->execute())
		$this->rader = $this->_rs->rowCount(); // hvor mange rader ble satt inn, slettet osv
	else
		$this->_err_msg = $this->_rs->errorInfo();

	$this->_reset_bind();

	return $data;
}

}

$db=new pdo_ext('database.ini');

$sql="SELECT * FROM tabell WHERE felt1=:f1 AND felt2=:f2";
$db->parse($sql);

// valider input

// add_bind() og select_exec() kan legges i f.eks. foreach eller while løkke
// hvis man trenger å kjøre Selecten flere ganger med forskjellig 
// input verdier
$db->add_bind(':f1',$input['f1'],PDO::PARAM_STR);
$db->add_bind(':f2',$input['f2'],PDO::PARAM_INT);
$data=$db->select_exec();

echo '<pre>';
print_r($data);
echo '</pre>';
?>

 

 

 

Ini fil:

 

[database]
driver = mysql
host = 127.0.0.1
;port = 3306
username = bruker
password = passord
dbname = database_navn

 

 

Lenke til kommentar

Takker meget for utrolig hjelp! :D

 

Siden fungerer og jeg skal sjekke ut hvordan jeg kan forbedre det.

Men et spm. til, hva gjør -> i php? Jeg klarer ikke å skjønne det, og det er utrolig plagsomt ettersom at det er så mye brukt. Har lest på wikipedia og noen andre sider, men føler meg like dum for-det-om.

Lenke til kommentar

Det er objekt orientert, og peker til funksjoner eller variabler i ett objekt.

F.eks. i pdo_ext klassen min over så vil $this->_rs referere til variabelen $_rs som er definert i toppen med protected $_rs; $this er inneværende objekt. $this->parse() refererer til funksjonen parse i klassen/objektet.

 

Kan være greit å lære seg objekt orientert først som sist, jeg var lenge på hva er egentlig nytten, det fungerer jo greit med "vanlig" kode, og når jeg lærte meg det (grunnleggende, lærer enda) så ble det til "hvorfor har jeg ikke lært meg dette tidligere".

Lenke til kommentar

Skjønner hva du mener.

 

Er nesten redd for å si dette men tenkte slik jeg også når jeg først begynnte å lære mej PHP.

Trengte jo ikke noe mer enn ren html koding med meg før (Y) :p

 

 

 

Men skal ta å lære det!

Lenke til kommentar

hm, trur ikke jeg skjønner det.

 

Ser vertfall ikke hvordan dette kan vere nyttig og bli brukt i dynamiske sammenhenger. (Noe som irriterer meg fordi jeg ser flere og flere som bruker det i disse sammenhengene!).

 

Er så sur fordi jeg ikke skjønner det, får vondt i hue. xP

Lenke til kommentar

Hvordan bruker jeg OOP for å ehnte ut ID fra en url?

Fra f.eks

side.php?id=5

Det har ikke noe med OOP å gjøre, bruk $_GET eller alternativt filter_var() eller filter_input():

 

echo (int)$_GET['id'];

echo filter_var($_GET['id'],FILTER_SANITIZE_NUMBER_INT);

echo filter_input(INPUT_GET,'id',FILTER_SANITIZE_NUMBER_INT);

Hvordan bruker jeg OOP for å ehnte ut ID fra en url?

Fra f.eks

side.php?id=5

Det har ikke noe med OOP å gjøre, bruk $_GET eller alternativt filter_var() eller filter_input():

 

echo (int)$_GET['id'];

echo filter_var($_GET['id'],FILTER_SANITIZE_NUMBER_INT);

echo filter_input(INPUT_GET,'id',FILTER_SANITIZE_NUMBER_INT);

 

Det jeg gjor var:

 

1. overføre id'en fra "view sida" til "kode sida".

$side_ID = (int)$_GET['id'];

$test = new Funksjon();
$test->TestFunksjon($side_ID);


 

2. så gjøre den klar i "kode sida"

private $ID;
function TestFunksjon($side_ID) {
 $this->ID = (int)$side_ID;
 return ID;
}

 

3. så hente den ut igjen i "view sida".

echo $test->TestFunksjon();

 

 

Trur det var slik jeg gjor det. Har ikke tilgang til pc'en jeg brukte igår...

Lenke til kommentar

Merklig problem nå:

 

Denne fungerer:

SELECT * FROM stoff WHERE stoff.stoff_stoff_id=2

 

Men denne fungerer ikke:

SELECT * FROM stoff JOIN stoff_syre ON stoff.stoff_stoff_id = stoff_syre.stoff_stoff_id JOIN stoff_org ON stoff.stoff_stoff_id = stoff_org WHERE stoff.stoff_stoff_id = 3

(Denne testet jeg også ut med NATURAL JOIN, men samme resultatet)

 

 

Noen som aner hva som er gale? 0.o

Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
×
×
  • Opprett ny...