Διαγραφή κατηγοριών - υποκατηγοριών κτλ κτλ με ενα query

Συζητήσεις για την βάση δεδομένων MySQL και το phpMyAdmin

Συντονιστές: WebDev Moderators, Super-Moderators

Απάντηση
Άβαταρ μέλους
Khronos
Δημοσιεύσεις: 754
Εγγραφή: 11 Δεκ 2006 14:43
Τοποθεσία: Ηράκλειο

Διαγραφή κατηγοριών - υποκατηγοριών κτλ κτλ με ενα query

Δημοσίευση από Khronos » 29 Σεπ 2010 17:25

Λοιπόν, έχω ένα table με κατηγορίες, όπου κάθε κατηγορία μπορεί να έχει υποκατηγορίες και ούτω καθεξής...

categories
------------
id
parent_id
title

Γίνεται μόλις διαγράψω μια κατηγορία να διαγράφονται και οι υποκατηγορίες της κάθε υποκατηγορίας με ένα query?

Ευχαριστώ

Άβαταρ μέλους
fafos
Script Master
Δημοσιεύσεις: 6231
Εγγραφή: 30 Νοέμ 2004 03:09

Διαγραφή κατηγοριών - υποκατηγοριών κτλ κτλ με ενα query

Δημοσίευση από fafos » 29 Σεπ 2010 17:44

epanelave.. den katalava auto: να διαγράφονται και οι υποκατηγορίες της κάθε υποκατηγορίας
Οι πάνες και οι πολιτικοί πρέπει να αλλάζονται συχνά για τον ίδιο λόγο...

Άβαταρ μέλους
Khronos
Δημοσιεύσεις: 754
Εγγραφή: 11 Δεκ 2006 14:43
Τοποθεσία: Ηράκλειο

Διαγραφή κατηγοριών - υποκατηγοριών κτλ κτλ με ενα query

Δημοσίευση από Khronos » 29 Σεπ 2010 17:51

πχ. έχουμε:

- Category1
..... subcategory1
..... subcategory2 <---------------
-------- subsubcategory1
-------- subsubcategory2
............... subsubsubcategory1


Εστω οτι διαγράφω την subcategory2, γίνεται να διαγραφούν και οι "από κάτω" κατηγορίες της με ένα query?

Άβαταρ μέλους
fafos
Script Master
Δημοσιεύσεις: 6231
Εγγραφή: 30 Νοέμ 2004 03:09

Διαγραφή κατηγοριών - υποκατηγοριών κτλ κτλ με ενα query

Δημοσίευση από fafos » 29 Σεπ 2010 18:02

Οι πάνες και οι πολιτικοί πρέπει να αλλάζονται συχνά για τον ίδιο λόγο...

Άβαταρ μέλους
Khronos
Δημοσιεύσεις: 754
Εγγραφή: 11 Δεκ 2006 14:43
Τοποθεσία: Ηράκλειο

Διαγραφή κατηγοριών - υποκατηγοριών κτλ κτλ με ενα query

Δημοσίευση από Khronos » 29 Σεπ 2010 18:07

Θα το τσεκάρω, ευχαριστώ ;)

Άβαταρ μέλους
Khronos
Δημοσιεύσεις: 754
Εγγραφή: 11 Δεκ 2006 14:43
Τοποθεσία: Ηράκλειο

Διαγραφή κατηγοριών - υποκατηγοριών κτλ κτλ με ενα query

Δημοσίευση από Khronos » 03 Νοέμ 2010 12:16

Για το ίδιο μοντέλο κατηγοριών, έστω ότι έχουμε προϊόντα που ανήκουν σε ΜΙΑ από τις παραπάνω κατηγορίες.

Πώς θα είναι το query για να τραβάω τα προϊόντα, όχι μόνο της κατηγορίας που επιλέχτηκε αλλά και τα προϊόντα που ανήκουν στις υποκατηγορίες της συγκεκριμένης κατηγορίας.

Χρησιμοποιώ το adjacency list model.

Ευχαριστώ

Άβαταρ μέλους
Khronos
Δημοσιεύσεις: 754
Εγγραφή: 11 Δεκ 2006 14:43
Τοποθεσία: Ηράκλειο

Διαγραφή κατηγοριών - υποκατηγοριών κτλ κτλ με ενα query

Δημοσίευση από Khronos » 03 Νοέμ 2010 15:26

Υπάρχει κάτι πιο σωστό απο αυτό?

Κώδικας: Επιλογή όλων

function get_path&#40;$parentId&#41; &#123;
	$sql = "SELECT id, title, parentId FROM categories WHERE parentId = $parentId";
	$res = mysql_query&#40;$sql&#41; or die&#40;mysql_error&#40;&#41;&#41;;
	
	$ids = array&#40;&#41;; 
	
	if&#40;mysql_num_rows&#40;$res&#41; > 0&#41; &#123;
		while&#40;$row = mysql_fetch_assoc&#40;$res&#41;&#41; &#123;
			$ids&#91;&#93; = $row&#91;'id'&#93;; 
			$ids = array_merge&#40;get_path&#40;$row&#91;'id'&#93;&#41;, $ids&#41;; 
		&#125;
	&#125;	
	return $ids;
&#125;

$ids = get_path&#40;1&#41;;
array_push&#40;$ids, 1&#41;;

$sql = "SELECT title FROM products WHERE categoryId IN &#40;".implode&#40;',', $ids&#41;."&#41;";

Άβαταρ μέλους
dva_dev
Script Master
Δημοσιεύσεις: 3790
Εγγραφή: 16 Σεπ 2005 01:32
Επικοινωνία:

Διαγραφή κατηγοριών - υποκατηγοριών κτλ κτλ με ενα query

Δημοσίευση από dva_dev » 03 Νοέμ 2010 16:47

Θα μπορούσες ίσως να δοκιμάσεις και κάτι σε άλλο στύλ:

Κώδικας: Επιλογή όλων

$sql="SELECT title FROM products WHERE categoryId IN &#40;SELECT id FROM categories WHERE parentId=$your_id OR id=$your_id&#41;";

Άβαταρ μέλους
Khronos
Δημοσιεύσεις: 754
Εγγραφή: 11 Δεκ 2006 14:43
Τοποθεσία: Ηράκλειο

Διαγραφή κατηγοριών - υποκατηγοριών κτλ κτλ με ενα query

Δημοσίευση από Khronos » 03 Νοέμ 2010 18:09

Έτσι όμως θα πάρω τα προϊόντα της κατηγορίας που επέλεξα και των κατηγοριών που βρίσκονται ΕΝΑ μόνο επίπεδο παρακάτω, έτσι δεν είναι?

Άβαταρ μέλους
dva_dev
Script Master
Δημοσιεύσεις: 3790
Εγγραφή: 16 Σεπ 2005 01:32
Επικοινωνία:

Διαγραφή κατηγοριών - υποκατηγοριών κτλ κτλ με ενα query

Δημοσίευση από dva_dev » 03 Νοέμ 2010 19:10

Ναι, αυτό φέρνει μόνο ένα επίπεδο, είναι βασικά για να υπάρχει και μια διαφορετική προσέγγιση.
Πάντα σχεδόν κάνεις συμβιβασμούς ανάμεσα στην ταχύτητα και την ευελιξία. Αν θέλεις να έχεις κάτι γενικό να παίζει για απεριόριστα επίπεδα δεν μπορείς να μην χρησιμοποιήσεις κώδικα.
Εγώ πάντως θα πήγαινα προς την κατεύθυνση να χρησιμοποιήσω κώδικα (ακόμα και αν χρειαζόταν να έχω επιπλέον πεδία στον πίνακα) ώστε να φτιάξω το query που θα μου φέρνει τα πάντα (αλλά να ζητάω μια φορά μόνο -ή όσο γίνεται λιγότερες- από τη database δεδομένα), παρά να ζητάω συνέχεια από τη database και να χρειάζεται να την έχω συνέχεια αγκαζέ.

Άβαταρ μέλους
Khronos
Δημοσιεύσεις: 754
Εγγραφή: 11 Δεκ 2006 14:43
Τοποθεσία: Ηράκλειο

Διαγραφή κατηγοριών - υποκατηγοριών κτλ κτλ με ενα query

Δημοσίευση από Khronos » 03 Νοέμ 2010 19:30

Όταν λες "να χρησιμοποιήσω κώδικα" τι εννοείς?
Άρα στην προκειμένη περίπτωση πώς θα το έκανες εσύ?

Άβαταρ μέλους
fafos
Script Master
Δημοσιεύσεις: 6231
Εγγραφή: 30 Νοέμ 2004 03:09

Διαγραφή κατηγοριών - υποκατηγοριών κτλ κτλ με ενα query

Δημοσίευση από fafos » 03 Νοέμ 2010 21:50

mporeis na "loupareis" tis kathgories mexri na vreis thn teleutaia kai oles tis eggrafes sta products.. alla opos eipe kai o dva einai psilokourastiko gia ton server auto an oi eggrafes einai polles:

Κώδικας: Επιλογή όλων

<?
function list_products&#40;$parent, $level=0&#41;  &#123;
$products = array&#40;&#41;;


    $sql = "SELECT categories.id FROM categories
            WHERE categories.id = '$parent'
            ORDER BY  categories.sort_order";
		
			
    $res = mysql_query&#40;$sql&#41; or die&#40;mysql_error&#40;&#41;&#41;;
    while &#40;list&#40;$id&#41; = mysql_fetch_row&#40;$res&#41;&#41; &#123;

	    $pro = "SELECT id, name FROM product WHERE category_id='$id'";	
    $pro = mysql_query&#40;$pro&#41; or die&#40;mysql_error&#40;&#41;&#41;;		
    while &#40;list&#40;$pid, $name&#41; = mysql_fetch_row&#40;$pro&#41;&#41; &#123;

	if&#40;$name&#41;&#123;	
	$products&#91;&#93; = $name;

	&#125; else &#123; echo '';&#125;	
	&#125;	
     
    &#125;




    $sql = "SELECT categories.id FROM categories
            WHERE categories.parent_id = '$parent'
            ORDER BY  categories.sort_order";
		
			
    $res = mysql_query&#40;$sql&#41; or die&#40;mysql_error&#40;&#41;&#41;;
    while &#40;list&#40;$id&#41; = mysql_fetch_row&#40;$res&#41;&#41; &#123;

	    $pro = "SELECT DISTINCT&#40;id&#41;, name FROM product WHERE category_id='$id' AND category_id !='$id'";	
    $pro = mysql_query&#40;$pro&#41; or die&#40;mysql_error&#40;&#41;&#41;;		
    while &#40;list&#40;$pid, $name&#41; = mysql_fetch_row&#40;$pro&#41;&#41; &#123;		
		if&#40;$name&#41;&#123;		
	$products&#91;&#93; =	$name;
	
		&#125; else &#123; echo '';&#125;		
	&#125;	

        list_products&#40;$id, $level+1&#41;;
	
    &#125;



//ektyposh

foreach &#40;$products as $value&#41; &#123;
echo $value.'<br>';
    
&#125;

&#125;

$parent = 1;//id kathgorias
list_products&#40;$parent,0&#41;;

?>
Οι πάνες και οι πολιτικοί πρέπει να αλλάζονται συχνά για τον ίδιο λόγο...

Άβαταρ μέλους
dva_dev
Script Master
Δημοσιεύσεις: 3790
Εγγραφή: 16 Σεπ 2005 01:32
Επικοινωνία:

Διαγραφή κατηγοριών - υποκατηγοριών κτλ κτλ με ενα query

Δημοσίευση από dva_dev » 03 Νοέμ 2010 23:15

Khronos έγραψε:Όταν λες "να χρησιμοποιήσω κώδικα" τι εννοείς?
Άρα στην προκειμένη περίπτωση πώς θα το έκανες εσύ?
Μια πιθανή πρόταση για να ξεκουράσεις λίγο τη database θα μπορούσε να είναι να βάλεις ένα πεδίο `level` στον πίνακα categories που να κρατάει το βάθος (ή ύψος) που βρίσκεται ο κάθε κόμβος, ώστε να μπορείς να βρεις πόσο είναι το μέγιστο ύψος που μπορεί να έχει το υποδέντρο που επιλέγεις. Αν μπορείς να κρατάς με κάποιο τρόπο στοιχεία για το πόσο είναι το πραγματικό ύψος του υποδέντρου του κάθε κόμβου, ίσως είναι ακόμα καλύτερα. Αν σε ενδιαφέρει μπορείς να εξετάσεις και αυτό το ενδεχόμενο και κατά πόσο αξίζει τον κόπο (για μένα μάλλον αξίζει γιατί η ενημέρωση θα χρειαστεί να γίνει μόνο στα inserts, αλλά τα selects όχι μόνο επειδή είναι πολλαπλάσια θα είναι και πιο ακριβή).

Αυτό που έχω να προτείνω χωρίς να το έχω ξεψυρίσει εντελώς, ψάχνει να βρεί το μέγιστο πιθανό ύψος του υποδέντρου, από το μέγιστο ύψος του συνολικού δέντρου - το ύψος του κόμβου, και φτάχνει ένα query string (βγαίνει αρκετά μεγάλο αν είναι πολλά τα επίπεδα που θα χρειαστεί να ψάχνει).
Αυτό το query string θα σταλεί μία φορά στη βάση και θα φέρει όλα τα αποτελέσματα από τον products.

Ετσι συνολικά, όσα επίπεδα κι αν έχεις στις κατηγορίες, όσους κόμβους κι αν έχεις, θα καλέσει τη database 2 φορές μόνο, όταν δεν μπορεί να γίνει διαφορετικά. Μια φορά για να βρεί το μέγιστο πιθανό ύψος του υποδέντρου, και τη δεύτερη για να φέρει τα products.

Κώδικας: Επιλογή όλων

<?php
function FindMaxDepth&#40;$searchid&#41;
&#123;
	$depthQuery = "
		SELECT MAX&#40;depth&#41; maxdepth FROM &#40;
			SELECT ifnull&#40;maxlevel-`level`+1,0&#41; depth
			FROM categories, &#40;SELECT MAX&#40;level&#41;maxlevel from categories&#41; tmp
			WHERE id=$searchid UNION SELECT 0 depth
		&#41;tmp1
	";
	$rset = mysql_query&#40; $depthQuery &#41;;
	list&#40;$maxdepth&#41; = mysql_fetch_row&#40;$rset&#41;;

	return intval&#40;$maxdepth&#41;;
&#125;

function CreateProductsQuery&#40;$searchid, $depth&#41;
&#123;
	$tmp = 'SELECT title from products INNER JOIN &#40;'."\n";
	for &#40;$level = 1; $level <= $depth; $level++&#41;
	&#123;
		if &#40;$level>1&#41; &#123;
			$tmp .= 'UNION '."\n";
		&#125;

		$tmp .= sprintf&#40;'SELECT c%d.id FROM categories c1 ', $level&#41;."\n";
		
		for &#40;$curr = 2; $curr <= $level; $curr++&#41;
		&#123;
			$tmp .= sprintf&#40;'left outer join categories c%d on c%d.id = c%d.parentid ', $curr, $curr-1, $curr&#41;."\n";
		&#125;
		$tmp .= sprintf&#40;'where c1.id=%d ', $searchid&#41;."\n";
	&#125;
	$tmp .= '&#41;ids ON products.categoryid = ids.id;'."\n";

	return $tmp;
&#125;

//The id to fetch full subtree
$searchid = 1;

//find subtree max possible depth
$depth = FindMaxDepth&#40;$searchid&#41;;
//Create subtree query
$subtreeQuery = CreateProductsQuery&#40;$searchid, $depth&#41;;
$rsetProducts = mysql_query&#40;$subtreeQuery&#41;;

//fetch products rows...
?>
Ιαως κάποιος άλλος να ρίξει στο τραπέζι κάποια εντελώς διαφορετική προσέγγιση.

ΥΓ. Τα $tmp .= blablabla ."\n" στον κώδικα τα έχω βάλει για να μπορείς να εκτυπώσεις το query και να διαβάζεται ανθρώπινα.

Άβαταρ μέλους
Khronos
Δημοσιεύσεις: 754
Εγγραφή: 11 Δεκ 2006 14:43
Τοποθεσία: Ηράκλειο

Διαγραφή κατηγοριών - υποκατηγοριών κτλ κτλ με ενα query

Δημοσίευση από Khronos » 04 Νοέμ 2010 00:19

Ευχαριστώ για τις απαντήσεις. Θέλουν μελέτη...
Όποιος έχει πάντως και άλλη λύση, ας τη δώσει να έχουμε υλικό!

pimpogio
Δημοσιεύσεις: 1080
Εγγραφή: 28 Δεκ 2010 14:08

Διαγραφή κατηγοριών - υποκατηγοριών κτλ κτλ με ενα query

Δημοσίευση από pimpogio » 17 Ιαν 2011 11:30

Khronos έγραψε:Λοιπόν, έχω ένα table με κατηγορίες, όπου κάθε κατηγορία μπορεί να έχει υποκατηγορίες και ούτω καθεξής...

categories
------------
id
parent_id
title

Γίνεται μόλις διαγράψω μια κατηγορία να διαγράφονται και οι υποκατηγορίες της κάθε υποκατηγορίας με ένα query?

Ευχαριστώ
ειναι πανευκολο αυτο που ζητας ...
εστω οτι εχουμε το σχημα

Κώδικας: Επιλογή όλων

--
-- Δομή Πίνακα για τον Πίνακα `cat`
--

CREATE TABLE `cat` &#40;
  `id` int&#40;10&#41; unsigned NOT NULL AUTO_INCREMENT,
  `pid` int&#40;10&#41; unsigned NOT NULL,
  `title` varchar&#40;128&#41; DEFAULT NULL,
  PRIMARY KEY &#40;`id`&#41;,
  UNIQUE KEY `title_UNIQUE` &#40;`title`&#41;,
  KEY `pid` &#40;`pid`&#41;
&#41; ENGINE=InnoDB  DEFAULT CHARSET=utf8;

--
-- Άδειασμα δεδομένων του πίνακα `cat`
--

INSERT INTO `cat` &#40;`id`, `pid`, `title`&#41; VALUES
&#40;1, 1, 'cat1'&#41;,
&#40;2, 1, 'subcat1'&#41;,
&#40;3, 1, 'subcat2'&#41;,
&#40;4, 2, 'subsubcat1'&#41;,
&#40;5, 2, 'subsubcat2'&#41;;

--
-- Περιορισμοί για πίνακα `cat`
--
ALTER TABLE `cat`
  ADD CONSTRAINT `pidindx` FOREIGN KEY &#40;`pid`&#41; REFERENCES `cat` &#40;`id`&#41; ON DELETE CASCADE ON UPDATE CASCADE;

DELETE FROM `cat` WHERE `cat`.`id` = 2

και σβηνεις την κατηγορια subcat1 με ολες τις υποκατηγοριες της...

Η InnoDB εχει τη δυναμη που υποστηριζει foreign keys
η MyISAM πολυ απλα δεν κανει για relation κατηγοριων
ασχετα που μερικα cms την χρησιμοποιουνε λαθος για αναλογα relations ...
και κανουνε καγκουριες μετα στον κωδικα για να κανουνε αυτα που πρεπει να
κανει η database..

Απάντηση

Επιστροφή στο “MySQL”

Μέλη σε σύνδεση

Μέλη σε αυτήν τη Δ. Συζήτηση: Δεν υπάρχουν εγγεγραμμένα μέλη και 0 επισκέπτες