J'analyse une base de données/code héritée plutôt horrible, en essayant de réduire la charge du serveur en combinant des requêtes en jointures (y compris un travail cron d'alerte par courrier électronique qui appelle généralement plus d'un million de requêtes distinctes).
SELECT * FROM
class_alerts_holding ah
INNER JOIN class_listings l ON l.id = ah.lid
INNER JOIN class_users u ON u.id = ah.uid
LEFT JOIN class_prodimages pi ON pi.pid = ah.lid
Cela crache 120 colonnes ...
aid | id | lid | uid | oid | catName | searchtext | alertfreq | listType | id | owner | title | section | shortDescription | description | featured | price | display | hitcount | dateadded | expiration | url | notified | searchcount | repliedcount | pBold | pHighlighted | notes | ...
Pour faciliter mon analyse de la manière de construire les nouvelles requêtes, il serait génial de pouvoir préfixer les colonnes du résultat avec la table dont elles proviennent dans JOIN, par exemple.
class_alerts_holding.aid | class_alerts_holding.id | class_listings.lid | ...
Y a-t-il un moyen d'y parvenir?
Vous pourriez
select ah.*, l.*, u.*, pi.* from ...
alors les colonnes seront retournées classées par table au moins.
Pour une meilleure distinction entre tous les deux ensembles de colonnes, vous pouvez également ajouter des colonnes "délimiteurs" comme ceci:
select ah.*, ':', l.*, ':', u.*, ':', pi.* from ...
(Modifié pour supprimer les alias explicites comme inutiles, voir les commentaires.)
Vous pouvez nommer les champs de votre requête et leur donner des alias:
SELECT ah.whateverfield1 AS 'ah_field1',
ah.whateverfield2 AS 'ah_field2',
l.whateverfield3 AS 'l.field3',
[....]
FROM class_alerts_holding ah
INNER JOIN class_listings l ON l.id = ah.lid
INNER JOIN class_users u ON u.id = ah.uid
LEFT JOIN class_prodimages pi ON pi.pid = ah.lid
C'est un peu difficile à configurer manuellement si vous avez autant de champs, mais vous pouvez le simplifier avec cette requête ...
SHOW FULL FIELDS FROM your_table_name;
... et un bon éditeur de texte et copier/coller.
Pour nommer les colonnes de façon dynamique, vous devez générer une instruction préparée faisant référence à information_schema. Cela vous donnerait les résultats que vous recherchiez.
SET @sql = NULL;
SELECT CONCAT(
'SELECT ',GROUP_CONCAT(c.TABLE_NAME,'.',c.COLUMN_NAME,' AS `',c.TABLE_NAME,'.',c.COLUMN_NAME,'`'),'
FROM class_alerts_holding
INNER JOIN class_listings ON class_listings.id = class_alerts_holding.lid
INNER JOIN class_users ON class_users.id = class_alerts_holding.uid
LEFT JOIN class_prodimages ON class_prodimages.pid = class_alerts_holding.lid'
)
INTO @sql
FROM INFORMATION_SCHEMA.COLUMNS c
WHERE c.TABLE_NAME IN ('class_alerts_holding','class_listings',
'class_users','class_prodimages');
PREPARE sql_statement FROM @sql;
EXECUTE sql_statement;
La fonction GROUP_CONCAT () a une limite par défaut de 1024 caractères. Par conséquent, en fonction du nombre de colonnes dans vos tables, vous devrez peut-être augmenter cette limite pour générer l'instruction préparée.
SET SESSION group_concat_max_len = 1000000;
Cette commande augmentera la limite de concaténation du groupe si nécessaire. -
Sur la base de la solution proposée par koljaTM et AndriyM, une solution encore meilleure consiste peut-être à rédiger votre requête de la manière suivante:
select
'--TABLE_AAA:--', TABLE_AAA.*,
'--TABLE_BBB:--', TABLE_BBB.*,
'--TABLE_CCC:--', TABLE_CCC.*,
'--TABLE_DDD:--', TABLE_DDD.*
from ...
Malheureusement, cela n’est toujours pas suffisant dans les cas où un (ou plusieurs) des tableaux contient plus de noms de colonnes que ce qui peut en contenir sur la largeur de l’écran. (Vous pouvez donc voir sur votre écran 20 colonnes mais ne pas encore voir le nom de la table d’où elles viennent.)
Il aurait quand même été préférable que SQL fournisse un moyen de préfixer automatiquement les noms de colonnes avec les noms de tables ...
J'ai trouvé quelque chose d'utile dans cette question MySQL concat () pour créer des noms de colonne à utiliser dans une requête? . Je pense que cela peut être l'une des solutions.
@ alden-w, vous pouvez ajouter une condition TABLE_SCHEMA à l'endroit où vous ne devez pas mélanger les mêmes noms de table de différents schémas
WHERE c.TABLE_SCHEMA='YOUR_SCHEMA_NAME' AND c.TABLE_NAME IN (....)