Allereerst bedankt als je me wilt helpen met het volgende probleem. Wellicht zit ik er helemaal naast...
Ik heb een stukje code geschreven om van alle landen over de wereld de bijbehorende provincies, districten, counties etc. erbij te zetten. Nu is het geval dat ik bij een land de districten onder hun Counties wil plaatsen. Hiervoor hebben de Counties een vaste code en de Districten heb ik zo gemaakt dat ze de bij behorende County codes bevatten. Echter is het probleem nu dat ik het niet voor elkaar krijg om de Districten onder de juiste County te zetten.
Dit is wat ik wil:
County 1
- District 1
- District 3
- District 6
County 2
- District 2
- District 4
- District 5
etc.
Maar ik krijg nu dit (voorbeeld, niet exacte namen):
County 1
County 2
District 1
District 2
District 3
District 4
District 5
District 6
Script hieronder laat de generated codes achter de Districten zien:
Je wilt dus een multi-level lijststructuur? Waarbij je feitelijk oneindig veel levels onder je parent hebt?
Dan moet je deze genormaliseerd opslaan, en recursief ophalen.
Dus een lijst zoals; Europa, Benelux, Nederland, Noord-Holland, Alkmaar (gemeente), Alkmaar.
<?php
// get all menuitems with 1 query
$result = mysqli_query($con,"
SELECT
id, parentId, name
FROM
menu
ORDER BY
parentId, name
");
// prepare special array with parent-child relations
$menuData = array(
'items' => array(),
'parents' => array()
);
while ($menuItem = mysqli_fetch_assoc($result))
{
$menuData['items'][$menuItem['id']] = $menuItem;
$menuData['parents'][$menuItem['parentId']][] = $menuItem['id'];
}
// menu builder function, parentId 0 is the root
function buildMenu($parentId, $menuData)
{
$html = '';
if (isset($menuData['parents'][$parentId]))
{
$html = '<ul>';
foreach ($menuData['parents'][$parentId] as $itemId)
{
$html .= '<li>' . $menuData['items'][$itemId]['name'];
// find childitems recursively
$html .= buildMenu($itemId, $menuData);
$html .= '</li>';
}
$html .= '</ul>';
}
return $html;
}
// output the menu
echo buildMenu(0, $menuData);
?>
Ofwel je ordent de resultaten in je database-query -aangenomen dat $row een resultaatrij van een query is- met een ORDER BY clause, of je bouwt in PHP een kleine datastructuur zodat je daar (volg)orde aanbrengt in de resultaten.
Dit is een relatief eenvoudig sorteerprobleem lijkt mij, daarna is het een kwestie van de resultaten achter elkaar uitdraaien.
Ik heb je script bekeken, maar moet ik uit je reactie concluderen dat het niet mogelijk is om met gegenereerde codes (child) naar een parent te leiden?
County (fixed code)
District (generated code)
Voorbeeld:
County - AL-01 (uit database)
District - AL-01 (deze AL-01 is gegenereerd)
// Change character set to utf8
if (!$conn->set_charset("utf8")) {
printf("Error loading character set utf8: %s\n<br />", $conn->error);
} else {
printf("Current character set: %s\n<br />", $conn->character_set_name());
}
// SQL join
$sql = "SELECT * FROM `iso3166-1`
LEFT JOIN `iso3166-2` ON `iso3166-1`.`numeric` WHERE `iso3166-1`.`numeric` = `iso3166-2`.`numeric`
UNION -- use UNION ALL to retain common rows
SELECT * FROM `iso3166-1`
RIGHT JOIN `iso3166-2` ON `iso3166-1`.`numeric` WHERE `iso3166-1`.`numeric` = `iso3166-2`.`numeric`";
// Get SQL results
$result = mysqli_query($conn, $sql);
if (!$result) {
echo "Could not successfully run query ($sql) from DB: ".mysqli_error($conn)."<br />";
exit;
}
$check_previous = "";
$same = false;
if (mysqli_num_rows($result) == 0) {
echo "No rows found, nothing to print so am exiting<br />";
exit;
}
// While Loop
while ($row = mysqli_fetch_assoc($result)) {
if ($same==true) {
// we know $same is true but are they really the same?
if ($check_previous=$shortname) {
$same=true;
//echo $same;
} else {
$same=false;
$row['shortname']="";
//echo $same;
}
} else {
// we are not sure that is it the same... need check
if ($check_previous=$shortname) {
//now we are 100% sure it is the same
$same=true;
}
if ($check_previous!=$shortname) {
//now we are 100% sure it is NOT the same
$same=false;
}
}
[size=xsmall]Toevoeging op 06/04/2019 13:43:01:[/size]
Thomas van den Heuvel, ik begrijp je maar dit kan niet als de code pas in een While Loop word gegenereerd.
Adoptive Solution, ja zoiets, alhoewel ik het een beetje anders wil hebben in design ;-) Daarnaast is mijn probleem nu echter of ik gegenereerde child codes kan linken aan gefixeerde codes
Een toekenning zelf heeft ook een resultaat. Dit kan mogelijk tot gevolg hebben dat een if-statement niet doet wat je zou verwachten.
Het resultaat van $test = 'x' is 'x'. Als je dus zoiets doet:
<?php
$test = 'a';
if ($test = 'b') {
// dit gedeelte wordt uitgevoerd
}
?>
Immers, het resultaat van de toekenning $test = 'b' is 'b' en dit is ongelijk aan een false-achtige waarde, dus het if-statement voldoet en het bijbehorende codeblok wordt uitgevoerd.
Controleer je echter op de volgende wijze:
<?php
$test = 'a';
if ($test == 'b') {
// dit gedeelte wordt niet uitgevoerd
}
?>
Ik heb de genereerde codes eruit gehaald en de database genormaliseerd.
Echter ik krijg ORDER BY hier niet aan het werk... Kan ik ORDER BY wel gebruiken by JOIN's?
(Ter info: `iso3166-2`.`subdivision_parent` bevat nu dezelfde code (is hier dus een Child) dat een code in `iso3166-2`.`subdivision_code` (=Parent) gekoppeld kan worden)
<?php
$sql = "SELECT * FROM `iso3166-1`
LEFT JOIN `iso3166-2` ON `iso3166-1`.`numeric` WHERE `iso3166-1`.`numeric` = `iso3166-2`.`numeric`
UNION -- use UNION ALL to retain common rows
SELECT * FROM `iso3166-1`
RIGHT JOIN `iso3166-2` ON `iso3166-1`.`numeric` WHERE `iso3166-1`.`numeric` = `iso3166-2`.`numeric`
ORDER BY `iso3166-2`.`subdivision_parent`";
?>
De veldnaam 'subdivision_code' is al compleet, bijvoorbeeld :
AD Andorra la Vella AD-07
Indien de landencode in de subdivision_code onbreekt, dan zou het er zo uit kunnen zien :
AD Andorra la Vella 07
Omdat ik uit je php code opmaak dat je de landencode en de subdivision code nog moet samenvoegen, kan je iets dergelijk al in MySQL doen.
SELECT
UPPER(Alpha2Code) AS Code,
CountryName AS Name,
CONCAT(Alpha2Code,'-',subdivision_code) AS SubCode,
subdivision_name AS Subdivision
FROM
iso3166_1
LEFT JOIN
iso3166_2
ON
Alpha2Code = country_code
WHERE
Alpha2Code >= 'MA'
AND
Alpha2Code <= 'MZ'
ORDER BY
Name, Subdivision
Het resulaat zou er dan zo uit kunnen zien :
Code Name SubCode Subdivision
MA Morocco MA-05 Beni-Mellal-Khenifra
MA Morocco MA-06 Casablanca-Settat
MA Morocco MA-08 Draa-Tafilalet
Adoptive Solution, ik heb met je code zitten spelen. Je hebt een mooie manier gevonden. Echter krijg ik het niet voor elkaar met mijn eigen data. Daarnaast zie ik geen COUNTY (dat is geen COUNTRY) en zie ik geen onderscheid tussen de subdivisions (zoals COUNTY, DISTRICT, PROVINCE etc.). Dat laatste is nou net wat ik zocht...
Ik ga jullie mijn voorbeeld verbeteren met data voorbeelden. Hopelijk helpt dat...
Voorbeeld: bij een land waarbij COUNTIES en de daarbij horende DISTRICTEN bekend zijn:
COUNTRY
- COUNTY
-- DISTRICT
Zo komt het bijvoorbeeld eruit te zien:
Albania
- Berat - County
-- Berat - District
-- Kuçovë - District
-- Skrapar - District
- Dibër - County
- Durrës - County
etc...
Voorbeeld: bij een land waarbij alleen PROVINCIES bekend zijn (waarbij later de gemeentes per provincies erbij komen):
COUNTRY
- PROVINCE
(-- COMMUNITIES) // De gemeentes
Zo komt het bijvoorbeeld eruit te zien:
Afghanistan
- Badakhsh?n - Province
- B?dgh?s - Province
- Baghl?n - Province
- Balkh - Province
- B?my?n - Province
- D?ykund? - Province
etc...
Zo kan elk land een andere indeling hebben, maar dat is nu even ter info voor jullie.
Mijn database structuren zijn:
iso3166-1 (Tabelnaam)
- id - int(11) -> 1 (oplopend)
- history - int(1) -> 0 (of 1 wanneer dit record is verwijderd)
- shortname - varchar(255) -> Afghanistan
- nativename - varchar(255) -> ?????????
- alpha2 - char(2) -> AF
- alpha3 - char(3) -> AFG
- numeric - char(3) -> 004
iso3166-2
- id - int(11) -> 47 (oplopend)
- history - int(1) -> 0 (of 1 wanneer dit record is verwijderd)
- numeric - char(3) -> 008
- subdivision_code - varchar(6) -> AL-BR
- subdivision_name - varchar(255) -> Berat
- category - varchar(255) -> District
- subdivision_parent - char(5) -> AL-01
mijn volledige php code staat in een bericht hierboven.
Hopend dat dit meer helpt. Fijn weekend allemaal.
[size=xsmall]Toevoeging op 07/04/2019 13:46:12:[/size]
Ter info: de nativenaam word hier weergegeven met ?????????. Echter zijn dit speciale characters.