mysql select from feltételhez_kötött_táblanevek

Van egy adatbázis, amin belül van egy 'cégek' tábla, ami tartalmazza a cégek főbb adatait. Minden cégnek van egy külön 'CÉGNEVE_országok' táblája, amiben a hozzá kapcsolódó országok paraméterei szerepelnek.

Azt szeretném elérni, hogy az összes 'CÉGNEVE_országok' táblából olvassa ki az országok neveit, hogy azt egy legördülő listában jelenítsem meg, így az adott országhoz tartozó cégeket akarom majd kiíratni.

Próbálkoztam sokféleképp, a megoldáshoz legközelebb talán ezzel jutottam:


SELECT * 
FROM (SELECT GROUP_CONCAT( table_name ) 
      FROM information_schema.tables 
      WHERE table_schema = 'adatbazis' AND table_name LIKE '%_orszagok'
     ) AS x

A belső SELECT szépen kidobja az érintett táblák vesszővel elválasztott listáját, de a külső SELECT-et nem tudom rávenni arra, hogy ebből a listából vegye a táblák neveit, és ne ennek a listának az elemeit (azaz egy darab sztringet) akarjon kiírni.

Rossz úton járok, vagy csak még nem találtam meg a megfelelő utasítást?

Hozzászólások

Ha az emlékeim nem csalnak, akkor ezt csak tárolt eljárással tudod megoldani.
A from után írt select arra való, hogy a külső select annak az eredményéből válogasson.

várj, te ugye nem SELECT *-ot akarsz? ahhoz össze kéne kapcsolni a táblákat. de még nem is SELECT orszag FROM ceg1_orszagok, ceg2_orszagok;

~~~~~~~~
deb http://deb.metaltux.tk/ wheezy testing

Ha az %_orszagok táblákban azonosak az oszlopok:
create view ORSZAGOK AS
select 'CEG1' CEGNEV, * from CEG1_ORSZAGOK
union
select 'CEG2' CEGNEV, * from CEG2_ORSZAGOK
....
union
select 'CEGX' CEGNEV, * from CEGX_ORSZAGOK;

A fent létrejött view-ból ízlés szerint szelektálgathatsz.

Amúgy ezt a %_orszagok jellegű particionálást el kellene felejteni (ha van rá lehetőség), mert elbonyolítja az alkalmazást, mint a mellékelt ábra is mutatja.

itt van egy eljárás tetszõleges számú %\_orszagok táblára


create temporary table tmp1 (orszag varchar(64));
DELIMITER //
CREATE PROCEDURE proc1()
BEGIN
  DECLARE done INT DEFAULT FALSE;
  DECLARE tbl VARCHAR(32);
  DECLARE cur1 CURSOR FOR SELECT table_name from information_schema.tables where table_schema = 'adatbazis' and table_name like '%\_orszagok';
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

  OPEN cur1;

  read_loop: LOOP
    FETCH cur1 INTO tbl;
    IF done THEN
      LEAVE read_loop;
    END IF;
    SELECT CONCAT("insert into tmp1 select orszag from ", tbl) INTO @stmt;
    PREPARE stmt1 FROM @stmt;
    EXECUTE stmt1;
    DEALLOCATE PREPARE stmt1;
  END LOOP;

  CLOSE cur1;
END
//
DELIMITER ;
SELECT orszag FROM tmp1;

mindazonáltal csatlakozom az elõttem szólóhoz, szuboptimális ez a db szervezés, illetve ha lehet, inkább szkriptbõl (php) ciklussal, több sql queryvel állítani össze a listát.

~~~~~~~~
deb http://deb.metaltux.tk/ wheezy testing

Köszönöm szépen a válaszokat!

Miután megírtam a kérdést, kb. 10 perce rá koppant, hogy (mivel php-ban használom) két külön lekérdezéssel lehet csak megoldani anélkül, hogy túlbonyolított sql utasításokkal rabolnám a saját időmet... (-_-') Mindenesetre már csak tiszteletből is áttanulmányozom a válaszként írt kódokat.

Ha nem így, akkor miként kellene megoldani, hogy minden cég adatai külön-külön vezetve legyenek? Miért baj, ha 'CÉGNEVE_országok'-ban tárolom a hozzá tartozó országok paramétereit? Vagy csak a LIKE '%_orszagok' a hülyeség?
--
A kényszer helyett a tudásvágy vezessen a tanulásban!

Nem akarlak tévútra vinni. Azt hiszem, adat (bázis) normalizálás a kulcsszó. A cégneveket, országok neveit ú.n. szótár táblákban szokás tárolni. De már annyira leépültem a nagy semmittevésben, hogy jobban jársz, ha bővebben valaki hozzáértő mesél róla.

Azt meg remélem, nem értettem félre, hogy most valami ilyen táblaneveket használsz:
ibm_hungary
microsoft_usa
stb.

Ha nem ezt csináltad, akkor részemről félreértés az egész.

Ha neked országonként kellenek adatok, akkor egyszerűen a rekordodban tárolod az országot - számkóddal, 2-/3-betűsen, teljes névvel, mindegy, ha konzisztens -, és az SQL-eid where/group by/having/order by részében szerepelteted a megfelelő kódokat.

Ha az adatbázismotorod támogatja a táblapartícionálást, így is izolálhatók az országdimenziók, de azt sejtem, nem a te rekordvolumened az, ahol erre szükség van.

Sokkal inkább szükség van az országot jelképező mező felvételébe minden olyan indexkulcsba, amely a fenti SQL-mondatrészeket támogatni képes.

"Egyébként miért nem használjuk azonosításra?"

Mert az adatbázisokból/-ba kódok szoktak dolgozni, amelyek természete az, hogy változnak - akár azért, mert az alapkoncepció volt téves, akár az igények változása miatt. Míg ma talán az az elvárás, hogy összesítéseket országonként kell adnod, holnap egy komplex, globális igény megizzaszthat, vagy csak felesleges iterációra késztet. És ez még hagyján, mert ennél messze kellemetlenebb, ha táblaváltoztatást/adatkarbantartást/törlést/migrációt kell végrehajtanod. Egy tábla (+segédtáblái, ha tovább van az adathalmaz normalizálva) feltételes műveletei helyett gányolásba torkollik a munka.

Érdemes szem előtt tartani azt, hogy az adatbáziskezelők létrehozásának egyik célja volt a kód logikájának és az adatok (manipulálásának) szétválasztása. Ha te táblaneveket dinamikusan generálsz, mert a logika függvénye a sok ugyanolyan tartalmú tábla közül a szükséges, akkor ezzel szembe mész.

adatbáziskezelés alapok.
olyasminek nézz utána, hogy normalizálás, 2nf, 3nf, bcnf, kapcsoló tábla.

itt kb az kell, hogy:

cegek: id, nev
orszag: id, nev
ceg_orszag: ceg_id, orszag_id

és kb. ennyi.

összes orszag_id kigyűjtése:
select distinct orszag_id from ceg_orszag

--
Gábriel Ákos
http://i-logic.hu

Azt hiszem kezdem érteni a dolgot. Eddig kb. így nézett ki az adatbázis:


CÉGEK
-----
egyik_cég  egyik_adat  másik_adat
másik_cég  egyik_adat  másik_adat
...

EGYIK_CÉG_ORSZÁGOK
------------------
H          egyik_adat  másik_adat
D          egyik_adat  másik_adat
USA        egyik_adat  másik_adat

MÁSIK_CÉG_ORSZÁGOK
------------------
CZ         egyik_adat  másik_adat
H          egyik_adat  másik_adat
SK         egyik_adat  másik_adat

Ha jól értem, akkor ezt ilyen formába kellene konvertálni:


CÉGEK
-----
egyik_cég  H,USA,D  egyik_adat  másik_adat
másik_cég  H,CZ,SK  egyik_adat  másik_adat
...

ORSZÁGOK
------------------
CZ         másik_cég  egyik_adat  másik_adat
D          egyik_cég  egyik_adat  másik_adat
H          egyik_cég  egyik_adat  másik_adat
H          másik_cég  egyik_adat  másik_adat
SK         másik_cég  egyik_adat  másik_adat
USA        egyik_cég  egyik_adat  másik_adat

Ha a céghez tartozó országokat akarom lekérdzeni, akkor kb. azt mondom, hogy 'válaszd ki az orzágokból azokat, amelyek a céghez vannak rendelve'. (persze a cég neve helyett egy id-vel kötöm össze őket)

Ami azt illeti így valóban egyszerűbbnek tűnik, az országok listája is egy pillanat alatt megvan egy lekérdezésből (az eddigi kettő helyett), azt hiszem ennél a megoldásnál maradok.

Köszönöm a segítségeteket!
--
A kényszer helyett a tudásvágy vezessen a tanulásban!

még visszább az alapokhoz, tessék megtanulni mi az a mező, mi tartozik egy mezőbe és mi nem.
országok neveit nem rakjuk egymás mellé vesszővel elválasztva.
ne sajnáld az adatbázist, ez nem excel, nincs miért spórolni a sorokkal.

--
Gábriel Ákos
http://i-logic.hu