2017-07-12 1 views
0

J'ai deux tables différentes pour obtenir des enregistrements dans une seule requête. Actuellement, j'utilise 2 requêtes puis fusionner le résultat du tableau et ensuite afficher l'enregistrement. À la suite de mon code actuel:Requête unique pour extraire des enregistrements de plusieurs tables avec des colonnes différentes

$db = JFactory::getDbo(); 
$query1 = "SELECT a.id as cId, a.title, a.parent_id,a.level FROM `categories` AS a WHERE (a.title LIKE '%keyword%')"; 
$result1 = $db->setQuery($query1)->loadObjectlist(); //gives selected records 

$query2 = "SELECT b.id as indId, b.indicator , b.cat_id, b.subcat_id, b.section_id FROM `indicator` as b WHERE (b.indicator LIKE '%keyword%')"; 
$result2 = $db->setQuery($query2)->loadObjectlist(); //gives selected records 

$_items = array_merge($result1,$result2); //then using $_items in php code to display the data 

Il est dans Joomla mais je veux juste savoir comment nous pouvons fusionner ces 2 requêtes en une seule. J'ai essayé le suivant mais il donne le résultat de la première requête de la table des catégories.

(SELECT id as cId, title, parent_id,level, NULL FROM `categories` WHERE (title LIKE '%birth%')) 
     UNION ALL 
(SELECT id as indId, indicator , cat_id, subcat_id, section_id FROM `indicator` WHERE (indicator LIKE '%birth%')) 

sortie souhaitée:

+------+-------------+------------+--------+--------+----------------+--------+-----------+----------+ 
| cId | title  | parent_id | level | indId | indicator  | cat_id | subcat_id | section_id 
+------+-------------+------------+--------+--------+----------------+--------+-----------+----------+ 
| 2874 | births  | 2703  | 2  | null | null   | null | null | null  | 
+------+-------------+------------+--------+--------+----------------+--------+-----------+----------+ 
| 13 | birth weight| 12  | 3  | null | null   | null | null  | null  | 
+------+-------------+------------+--------+--------+----------------+--------+-----------+----------+ 
| null | null  | null | null | 135 | resident births| 23 |  25 |  1 | 
+------+-------------+------------+--------+--------+----------------+--------+-----------+----------+ 
| null | null  | null | null | 189 | births summary | 23 |  25 |  1 | 
+------+-------------+------------+--------+--------+----------------+--------+-----------+----------+ 

Cette sortie ci-dessus vous aidera à obtenir les dossiers de paginations appropriés. J'ai essayé d'utiliser join mais JOIN a besoin d'une colonne commune dans ON clause. Ici, je veux toutes les colonnes et leurs valeurs. Fondamentalement, je veux combiner les 2 enregistrements de la table dans une requête. Toute aide serait appréciée

+0

Utilisez le concept de 'JOIN' requête – Sinto

+0

je pensais à cela, mais rejoindre aurait besoin de toute colonne commune et ici, je n'ai pas de colonne commune. Je veux toutes les colonnes –

Répondre

2

Voici un exemple,

Il y a plusieurs façons de le faire, en fonction de ce que vous voulez vraiment. En l'absence de colonnes communes, vous devez décider si vous souhaitez introduire une colonne commune ou obtenir le produit.

Disons que vous avez les deux tables:

parts:    custs: 
+----+----------+ +-----+------+ 
| id | desc  | | id | name | 
+----+----------+ +-----+------+ 
| 1 | Sprocket | | 100 | Bob | 
| 2 | Flange | | 101 | Paul | 
+----+----------+ +-----+------+ 

Oublier les colonnes réelles puisque vous auriez probablement avez un client/commande/relation partiel dans ce cas; Je viens d'utiliser ces colonnes pour illustrer les façons de le faire.

Un produit cartésien correspondra à chaque ligne de la première table avec chaque ligne de la seconde:

> select * from parts, custs; 
     id desc  id name 
     -- ----  --- ---- 
     1 Sprocket 101 Bob 
     1 Sprocket 102 Paul 
     2 Flange 101 Bob 
     2 Flange 102 Paul 

C'est probablement pas ce que vous voulez depuis 1000 pièces et 100 clients entraînerait 100.000 lignes avec beaucoup de dupliquée information. Alternativement, vous pouvez utiliser une union pour simplement sortir les données, mais pas côte à côte (vous devrez vous assurer que les types de colonne sont compatibles entre les deux sélections, soit en rendant les colonnes de table compatibles ou en les contraignant eux dans la sélection):

> select id as pid, desc, '' as cid, '' as name from parts 
    union 
    select '' as pid, '' as desc, id as cid, name from custs; 
    pid desc  cid name 
    --- ----  --- ---- 
       101 Bob 
       102 Paul 
    1 Sprocket 
    2 Flange 

dans certaines bases de données, vous pouvez utiliser un rowid/colonne rownum ou pseudo-colonne pour correspondre à des enregistrements côte à côte, comme:

id desc  id name 
-- ----  --- ---- 
1 Sprocket 101 Bob 
2 Flange 101 Bob 

le code serait quelque chose comme:

select a.id, a.desc, b.id, b.name 
from parts a, custs b 
where a.rownum = b.rownum; 

Il est encore comme un produit cartésien, mais les limites where clause comment les lignes sont combinées pour former les résultats (donc pas un produit de cartésienne du tout, vraiment).

Je n'ai pas testé ce SQL pour cela puisque c'est l'une des limitations de mon SGBD de choix, et à juste titre, je ne crois pas que ce soit jamais nécessaire dans un schéma bien pensé.Étant donné que SQL ne garantit pas l'ordre dans lequel il produit des données, la correspondance peut changer à chaque fois que vous effectuez la requête, sauf si vous avez une relation spécifique ou une clause order by.

Je pense que l'idéal serait d'ajouter une colonne aux deux tables en précisant la relation. S'il n'y a pas de véritable relation, alors vous n'avez probablement rien à faire pour les mettre côte à côte avec SQL.

+0

merci! la requête syndicale que vous avez expliquée m'a aidé à résoudre mon problème. Je ne prenais pas de colonnes factices pour d'autres tables et donc le problème arrivait. Je posterai ma requête correcte pour les avantages des autres –

0

Comme @Sinto suggère la réponse pour union et les noms de colonnes factices suivantes est toute requête correcte:

(SELECT id as cId, title, parent_id,level, NULL as indId, NULL as indicator , NULL as cat_id, NULL as subcat_id, NULL as section_id FROM `jm_categories` WHERE (title LIKE '%births%')) UNION ALL (SELECT NULL as cId, NULL as title, NULL as parent_id,NULL as level, id as indId, indicator , cat_id, subcat_id, section_id FROM `jm_indicator_setup` WHERE (indicator LIKE '%births%')) 

Nous devons faire correspondre les noms de colonnes des deux tables afin que nous obtenons des enregistrements en combinaison.