Insérer plusieurs lignes dans une table basée sur le nombre dans une autre table
Je suis entrain de créer une base de données pour la première fois à l'aide de Postgresql 9.3 sur MacOSX.
Disons que j'ai de la table A
et B
. Table A
commence comme vide et Table B
comme remplie. Je voudrais que le nombre d'entrées dans la colonne all_names
dans le tableau B
à l'égalité de la number
pour chaque names
dans le tableau A
comme la table B
ci-dessous. Ainsi names
doit contenir chaque entrée unique de all_names
et number
son compte. Je ne suis pas habitué à la syntaxe encore donc je ne sais pas vraiment comment aller à ce sujet. Le birthday
colonne est redondant.
Un
names | number
-------+------------
Carl | 3
Bill | 4
Jen | 2
B
all_names | birthday
-------+------------
Carl | 17/03/1980
Carl | 22/08/1994
Carl | 04/09/1951
Bill | 02/12/2003
Bill | 11/03/1975
Bill | 04/06/1986
Bill | 08/07/2005
Jen | 05/03/2009
Jen | 01/04/1945
Mise à JOUR: Serait-ce la bonne façon d'aller à ce sujet? insert into a (names, number) select b.all_names, count(b.all_names) from b group by b.all_names;
OriginalL'auteur jO. | 2013-10-01
Vous devez vous connecter pour publier un commentaire.
Réponse à la question d'origine
Postgres permet de définir-de retour des fonctions (SRF) de multiplier les lignes.
generate_series()
est votre ami:Toutefois, cette syntaxe est mal vu et peut être supprimée dans les versions futures.
Depuis l'introduction de
LATÉRALES
dans Postgresql 9.3 vous pouvez utiliser cela plus d'avenir version (SRF dans leFROM
liste à la place dans la liste des cibles):LATERAL
est implicite ici, comme expliqué dans le manuel:Opération inverse
Ci-dessus est l'opération inverse (environ) d'un simple agrégation
count()
:... qui s'adapte à votre mise à jour de question.
Il y a une différence subtile entre
count(*)
etcount(all_names)
. L'ancien compte toutes les lignes, n'importe quoi, alors que ce dernier ne prend en compte que les lignes oùall_names IS NOT NULL
. Si votre colonneall_names
est défini commeNOT NULL
, à la fois retour le même, maiscount(*)
est légèrement plus courte et plus rapide.Considérer cette réponse pour en savoir plus sur
GROUP BY 1
:GROUPE DE + de CAS
create table b (names text, number int);
insert into b (names) values ('bill'), ('bill'), ('jen');
select b.names from b, generate_series(1, b.number) as rn;
Pourquoi n'est-ce pas de travail? Merci.Dans votre exemple,
number
est NULL. Doncgenerate_series()
ne va pas générer toutes les lignes. Insérer des valeurs pournumber
.Merci pour votre réponse et votre aide. J'ai mis à jour ma question. J'ai réalisé qu'il pourrait ne pas avoir été assez clair ce que je recherchais, même pensé que votre réponse a fonctionné pour moi la première fois autour d' - curieusement depuis
generate_series()
l'habitude de travailler avec la valeur NULL. Je dois avoir entré les données, à tort. Merci beaucoup!Fondamentalement, vous êtes après l'opération inverse et votre solution devrait fonctionner. J'ai ajouté un peu de ma réponse.
OriginalL'auteur Erwin Brandstetter