web-dev-qa-db-fra.com

Puis-je utiliser les en-têtes de colonne dans un = QUERY?

Lecture de la documentation pour la fonction =QUERY1 , 2 , , une partie de cela semble impliquer que je devrais pouvoir utiliser des en-têtes de colonnes directement dans ma requête. Par exemple, la fonction =QUERYprend un troisième paramètre facultatif , HEADERS, qui vous permet de spécifier un nombre de lignes d'en-tête.

La plupart de mes requêtes seraient beaucoup plus jolies si je pouvais utiliser les en-têtes de colonnes, ainsi je n'aurais pas à utiliser les index de colonnes, mais je ne pourrais pas le faire fonctionner.

Exemple:

A      B         C
---------------------
Name   Phone     City
Vidar  12345678  Oslo
Rupert 32165487  Berlin

Je suis capable d'interroger ceci en utilisant des index de colonnes:

=QUERY(Sheet1!A1:C; "select A, B, C where A = 'Vidar'"; 1)

... mais n'utilise pas les en-têtes de colonnes:

=QUERY(Sheet1!A1:C; "select A, B, C where Name = 'Vidar'"; 1)

... cela me donne Erreur: Requête non valide: Colonne [ Nom] n'existe pas dans la table

Est-il possible d'utiliser des en-têtes de colonne comme celui-ci? Sinon, à quoi sert le paramètre HÈADERS?

14
Vidar S. Ramdal

Le troisième paramètre dont vous parlez dans la fonction QUERY est destiné à contrôler les en-têtes. S'il est défini sur -1, la feuille de calcul Google indique son propre choix dans le choix des en-têtes, en fonction des données disponibles: enter image description here

J'ai utilisé le jeu de données suivant: enter image description here

Si défini sur 0, aucun en-tête ne sera utilisé, laissant: enter image description here

Si défini sur 1, la première ligne sera utilisée, en laissant: enter image description here

S'il est défini sur 2 ou -1 ou left blank, les deux premières lignes seront utilisées, en laissant: enter image description here

Utiliser les en-têtes, comme vous l'avez fait dans votre exemple, n'est pas possible. La chose la plus proche serait l'utilisation de la fonction QUERY, décrite dans la réponse this. Un quasi-nom de colonne est utilisé.

3
Jacob Jan Tuinstra

Est-il possible d'utiliser des en-têtes de colonne comme celui-ci?

Oui c'est possible. Tout d'abord, vous devez utiliser MATCH pour obtenir le numéro de colonne de la colonne dont la valeur correspond à 'Nom'. Ensuite, vous devez utiliser ADDRESS pour obtenir la référence de cellule. Enfin, vous devez utiliser SUBSTITUTE pour supprimer le numéro de ligne de la référence de cellule.

=QUERY(Sheet1!A1:C,"SELECT A, B, C where "&SUBSTITUTE(ADDRESS(1,MATCH("Name",Sheet1!A1:C1,0),4),1,"")&" = 'Vidar'")
7
Dave Meindl

En tant que vieux message, je voulais ajouter ma solution au mélange. Vous pouvez utiliser des noms de colonnes que je trouve plus utiles. De cette façon, vous n'avez pas à modifier vos appels de fonction de requête lorsque vous insérez ou supprimez des colonnes dans les données source.

J'ai vu d'autres personnes utiliser la correspondance et la substitution, j'ai implémenté quelque chose d'un peu différent pour simplement l'appel de la fonction de requête.

Premier - Créez une table de recherche de tous vos noms de colonnes, comme ceci. Ma table de correspondance commence dans la colonne E d'une feuille 'Config' uniquement parce que d'autres éléments figurent sur la feuille. Elle pourrait facilement être placée dans sa propre feuille.

  • Colonne 1 (Nom de la colonne)

    =TRANSPOSE( 'Source Data'!1:1 )
    
  • Colonne 2 (Colonne #)

    =arrayformula( row( E2:E ) - 1 )
    
  • Colonne 3 (lettre de colonne)

    =arrayformula( if( int( F2:F / 26.5 ) > 0, char( int( F2:F / 26.5 )  + 64), "" ) & char( (F2:F - (int( F2:F / 26.5 ) * 26 ) ) + 64 ) )
    

    Je suis ouvert aux raffinements pour convertir un numéro de colonne en lettre. Cette formule est limitée en ce sens qu'elle ne gère que 78 colonnes. Plus que suffisant pour moi cependant.

Maintenant, votre appel à la fonction de requête ressemblerait à ceci:

=query( 'Source Data'!$A:$L,
"Select " & " " &
vlookup( "Date", Config!$E:$G, 3, false ) & ", " &
vlookup( "Dev Query Engine Conn Count", Config!$E:$G, 3, false ) & ", " &
vlookup( "Dev Conn Limit Retry Count", Config!$E:$G, 3, false ) & ", " &
vlookup( "Dev Max Sequential Retry in One Minute", Config!$E:$G, 3, false ) & ", " &
vlookup( "Dev Conn Limit Errors", Config!$E:$G, 3, false ) & " " &
"where " & vlookup( "Display in Graph.", Config!$E:$G, 3, false ) & "=TRUE " &
"order by " & vlookup( "Date", Config!$E:$G, 3, false ) & " desc "
)

Gardez-le bien formaté et ce n'est pas mal à gérer du tout. Si vous modifiez l'index de colonne de votre plage vlookup, vous ne souffrirez que. Mais cela ne devrait pas changer souvent, voire pas du tout, étant donné qu'il s'agit d'une gamme d'assistance.

3
Don

Vieille question, mais je pense que cette solution peut en valoir la peine.

Vous pouvez utiliser une fonction de script personnalisée qui récupère l'index de colonne (c'est-à-dire A, B, C ...) en utilisant un nom d'en-tête, permettant de faire quelque chose comme:

=query('MySheet'!A2:Z; 
   "select "&colIndex("'MySheet'!A1:Z1"; "Car name")&"  
    where "&colIndex("'MySheet'!A1:Z1"; "Car color")&"='Blue'"))

Avec la fonction colIndex:

function colIndex(a1NotationStr, header){
  var range = SpreadsheetApp.getActiveSpreadsheet().getRange(a1NotationStr)
  var row = range.getValues()[0]

  //parse the header row and stop at first header matching our search
  //use the related cell A1Notation and remove all numbers (i.e. 'A45' becomes 'A')
  for(var i=0; i<row.length; i++){
    var currHeader = row[i]
    if(currHeader == header){
      return range.getCell(1, i+1).getA1Notation().replace(/[0-9]/g, '');
    }  
  }
}

Ce qui peut être plus facile à utiliser et à lire.

3
Pierre B.