web-dev-qa-db-fra.com

Pourquoi ne puis-je pas utiliser alias dans un compte (*) "colonne" et le référencer dans une clause having?

Je me demandais pourquoi je ne pouvais pas utiliser alias dans un compte (*) et le référencer dans la clause having. Par exemple:

select Store_id as StoreId, count(*) as _count
    from StoreProduct
    group by Store_id
        having _count > 0

Cela ne fonctionnerait pas .. Mais cela fonctionne si je supprime _count et utilise plutôt count (*).

54
André Pena

Voir le document référencé par CodeByMoonlight dans une réponse à votre question récente .

La clause HAVING est évaluée avant le SELECT - le serveur n'est donc pas encore au courant de cet alias.

  1. Tout d'abord, le produit de toutes les tables de la clause from est formé.
  2. La clause where est ensuite évaluée pour éliminer les lignes qui ne satisfont pas la condition_recherche.
  3. Ensuite, les lignes sont regroupées à l'aide des colonnes de la clause group by.
  4. Ensuite, les groupes qui ne satisfont pas à la condition de recherche dans le having clause sont éliminés.
  5. Ensuite, les expressions de la liste des cibles de la clause select sont évalué.
  6. Si le mot clé distinct est présent dans la clause select, dupliquez les lignes sont maintenant éliminés.
  7. La union est prise après l'évaluation de chaque sous-sélection.
  8. Enfin, les lignes résultantes sont triées en fonction des colonnes spécifié dans la clause order by.
88
martin clayton

La clause select est la dernière clause à être exécutée logiquement, à l'exception de order by. La clause having étant antérieure à la sélection, les alias ne sont pas encore disponibles.

Si vous voulez vraiment utiliser un alias, mais que cela ne soit pas recommandé, une vue en ligne peut être utilisée pour rendre les alias disponibles:

select StoreId, _count
from (select Store_id as StoreId, count(*) as _count
    from StoreProduct
    group by Store_id) T
where _count > 0

Ou dans SQL Server 2005 et supérieur, un CTE:

; with T as (select Store_id as StoreId, count(*) as _count
    from StoreProduct
    group by Store_id)
select StoreId, _count
from T
where _count > 0
11
Shannon Severance

Vous pouvez utiliser l'alias pour count dans la clause select, mais vous ne pouvez pas l'utiliser dans la déclaration having, donc cela fonctionnerait.

select Store_id as StoreId, count(*) as _count
    from StoreProduct
    group by Store_id
        having count(*) > 0
3
Glenn Slaven

Voici ma contribution (basée sur le code affiché ici):

select * from (
  SELECT Store_id as StoreId, Count(*) as StoreCount 
  FROM StoreProduct
  group by Store_id
  ) data
where data.StoreCount > 0

Dans Hive 0.11.0 et les versions ultérieures, les colonnes peuvent être spécifiées par position si Hive.groupby.orderby.position.alias est défini sur true.

set Hive.groupby.orderby.position.alias=true;
select Store_id as StoreId, count(*) as _count
from StoreProduct
group by 1

Je ne comprends pas le but de votre requête… .. Étant donné le contexte de la requête que vous avez postée, votre condition n'est pas nécessaire car des éléments qui n'existent pas, i. e. compte 0, ne sera jamais le résultat d'une requête ...

0
rafaelvalle

Vous pouvez utiliser l'alias pour les agrégats dans SQL, mais c'est simplement pour afficher l'alias dans les en-têtes de résultats. Mais lorsque vous souhaitez avoir une condition avec la fonction d'agrégat, vous devez toujours utiliser l'agrégat, car il évalue la fonction et non le nom.

0
Jose Chama

Les alias des noms de champs servent uniquement à nommer les colonnes du résultat. Elles ne peuvent jamais être utilisées dans la requête. Vous ne pouvez pas faire comme ça non plus:

select Store_id as Asdf
from StoreProduct
where Asdf = 42

Cependant, vous pouvez utiliser count(*) en toute sécurité dans les deux emplacements, et la base de données reconnaîtra qu'il s'agit de la même valeur et ne sera donc pas calculée deux fois.

0
Guffa