J'ai le tableau suivant:
data['Unique_count'] = data.nunique(axis=1)
Maintenant, je veux compter le nombre de valeurs uniques par ligne et le stocker dans une nouvelle colonne appelée Unique_count
Donc, ma sortie attendue serait:
A B C Unique_count 0 10 10 10 1 1 20 10 20 2 2 30 20 10 3 3 40 40 40 1 4 50 20 20 2
Je suis familier avec SELECT DISTINCT . Mais ce sont toutes des opérations par colonne. Je ne peux pas comprendre comment compter par ligne en SQL.
Avec le module pandas en Python, ce serait simplement:
WITH data AS (
SELECT 10 AS A, 10 AS B, 10 AS C
UNION ALL
SELECT 20 AS A, 10 AS B, 20 AS C
UNION ALL
SELECT 30 AS A, 20 AS B, 10 AS C
UNION ALL
SELECT 40 AS A, 40 AS B, 40 AS C
UNION ALL
SELECT 50 AS A, 20 AS B, 20 AS C)
SELECT * FROM data;
A B C
0 10 10 10
1 20 10 20
2 30 20 10
3 40 40 40
4 50 20 20
3 Réponses :
Dans SQL Server, utilisez une jointure latérale - apply keyword`:
select t.*, v.unique_count
from t cross apply
(select count(distinct col) as unique_count
from (values (t.a), (t.b), (t.c)) v(col)
) v;
Une jointure latérale ressemble beaucoup à une sous-requête corrélée dans le de la clause - mais plus générale car la sous-requête peut renvoyer plus d'une colonne et plus d'une ligne.
Cette version fait exactement ce à quoi elle ressemble: elle décolle les colonnes puis utilise count (distinct) pour compter le nombre de valeurs uniques.
Dans MySQL, vous pouvez utiliser la logique conditionnelle:
| A | B | C | unique_count | | --- | --- | --- | ------------ | | 10 | 10 | 10 | 1 | | 20 | 10 | 20 | 2 | | 30 | 20 | 10 | 3 | | 40 | 40 | 40 | 1 | | 50 | 20 | 20 | 2 |
Cela fonctionne parce que MySQL évalue les conditions vrai / faux comme 1/0 dans un contexte numérique (cette fonctionnalité nous évite un long cas ici).
select
t.*,
1 + (a <> b) + (a <> c and b<>c) unique_count
from data t
Donc, fondamentalement, les booléens des deux conditions que vous additionnez, non?
@Erfan: oui chaque condition produit 1 en cas de succès (sinon 0), et les valeurs sont ajoutées. Cela vous donne le nombre de valeurs distinctes dans les 3 colonnes.
Je vois, belle approche hors de la boîte!
Généraliser cela à plus de 3 colonnes le rend un peu plus complexe, non?
@Barmar: oui, la complexité de la logique conditionnelle augmente drastiquement avec le nombre de colonnes; votre solution est un meilleur choix s'il y a beaucoup de colonnes.
Ajoutez une colonne id au tableau. Ensuite, vous pouvez utiliser UNION pour faire pivoter les colonnes en lignes, puis COUNT (*) pour obtenir les décomptes. Ensuite, joignez-le à la table d'origine.
Notez que vous n'avez pas besoin d'utiliser COUNT (DISTINCT) car UNION DISTINCT supprime les doublons.
WITH data AS (
SELECT 0 AS id, 10 AS A, 10 AS B, 10 AS C
UNION ALL
SELECT 1 AS id, 20 AS A, 10 AS B, 20 AS C
UNION ALL
SELECT 2 AS id, 30 AS A, 20 AS B, 10 AS C
UNION ALL
SELECT 3 AS id, 40 AS A, 40 AS B, 40 AS C
UNION ALL
SELECT 4 AS id, 50 AS A, 20 AS B, 20 AS C)
SELECT t1.*, t2.unique_count
FROM data AS t1
JOIN (
SELECT id, COUNT(*) AS unique_count
FROM (
SELECT id, A AS datum FROM data
UNION DISTINCT
SELECT id, B AS datum FROM data
UNION DISTINCT
SELECT id, C AS datum FROM data) AS x
GROUP BY id) AS t2
ON t1.id = t2.id