Limite de se joindre à une seule ligne
J'ai la requête suivante:
SELECT sum((select count(*) as itemCount) * "SalesOrderItems"."price") as amount, 'rma' as
"creditType", "Clients"."company" as "client", "Clients".id as "ClientId", "Rmas".*
FROM "Rmas" JOIN "EsnsRmas" on("EsnsRmas"."RmaId" = "Rmas"."id")
JOIN "Esns" on ("Esns".id = "EsnsRmas"."EsnId")
JOIN "EsnsSalesOrderItems" on("EsnsSalesOrderItems"."EsnId" = "Esns"."id" )
JOIN "SalesOrderItems" on("SalesOrderItems"."id" = "EsnsSalesOrderItems"."SalesOrderItemId")
JOIN "Clients" on("Clients"."id" = "Rmas"."ClientId" )
WHERE "Rmas"."credited"=false AND "Rmas"."verifyStatus" IS NOT null
GROUP BY "Clients".id, "Rmas".id;
Le problème c'est que la table "EsnsSalesOrderItems"
peut avoir le même EsnId
dans les différentes entrées. Je veux restreindre la requête de tirer seulement la dernière entrée dans "EsnsSalesOrderItems"
qui a le même "EsnId"
.
Par "dernier" entrée, je veux dire les éléments suivants:
Celui qui apparaît en dernier dans la table "EsnsSalesOrderItems"
. Donc par exemple si "EsnsSalesOrderItems"
a deux entrées avec "EsnId" = 6
et "createdAt" = '2012-06-19'
et '2012-07-19'
, respectivement, il ne devrait me donner de l'entrée de '2012-07-19'
.
OriginalL'auteur user1175817 | 2012-09-29
Vous devez vous connecter pour publier un commentaire.
Votre requête dans la question illégale d'un ensemble plus un autre agrégat:
Simplifié et converti juridique syntaxe:
Mais voulez-vous vraiment à se multiplier avec le comte par groupe?
- Je récupérer la ligne unique par groupe dans
"EsnsSalesOrderItems"
avecDISTINCT ON
. Explication détaillée:J'ai aussi ajouté des alias de table et mise en forme pour faire la requête plus facile à analyser pour les yeux humains. Si vous pouviez éviter de chameau cas, vous pourriez se débarrasser de tous les guillemets obscurcissement de la vue.
Bien sûr, avec un
"EsnId"
, mais parmi ceux avec ce code spécifique, qui allez-vous choisir? Définir le "dernier".Celui qui apparaît en dernier dans la table "EsnsSalesOrderItems". Ainsi par exemple, si "EsnsSalesOrderItems" a deux entrées avec le EsnId=6 et createdAt = 6-19-2012 et 7-19-2012, respectivement, il ne devrait me donner de l'entrée de 7-19-2012
- Je l'utiliser dans ma mise à jour de réponse. Cette information doit aller dans la question pour le rendre complet.
Est plus clair?
OriginalL'auteur Erwin Brandstetter
Quelque chose comme:
cela permet de sélectionner la dernière "
EsnId"
de"EsnsSalesOrderItems"
basé sur la colonnecreation_date
. Comme vous n'avez pas de poste de la structure de vos tables, j'ai dû "inventer" un nom de colonne. Vous pouvez utiliser n'importe quelle colonne vous permet de définir un ordre sur les lignes qui vous convient.Mais rappelez-vous le concept de la "dernière ligne" n'est valable que si vous spécifier une commande ou de l'lignes. Un tableau en tant que tel n'est pas ordonnée, ni le résultat d'une requête sauf vous spécifiez un
order by
Il n'y a pas de
EsnsSalesOrderItems
"table". Il s'appelle maintenantt
. Vous pouvez modifier l'aliast
àEsnsSalesOrderItems
ou tout simplement utilisert
au lieu tout au long de la requêteoui, je sais. c'est ce que je veux dire.
ma requête est identique à ci-dessus, sauf que j'ai remplacé les deux se rejoignent déclarations avec les éléments suivants:join ( select "EsnId", "SalesOrderItemId", row_number() over (order by "createdAt" desc) de rn de "EsnsSalesOrderItems" ) t t."EsnId" = "Rse"."id" et rn = 1 REJOINDRE "SalesOrderItems" ("SalesOrderItems"."id" = t".SalesOrderItemId")
LIMIT 1
limiterait à une seule ligne, période. Mais nous avons besoin d'une ligne par"EsnId"
. En conséquence, la première versionrow_number()
aurait besoin d'unPARTITION BY "EsnId"
de travail.OriginalL'auteur a_horse_with_no_name
Necromancing parce que les réponses sont obsolètes.
Profitez de la
LATERAL
mot-clé introduit dans PG 9.3gauche | droite | inner JOIN LATÉRALE
Je vais vous expliquer avec un exemple:
En supposant que vous avez une table "Contacts".
Maintenant, les contacts ont unités d'organisation.
Ils peuvent avoir une unité à un point dans le temps, mais N OUs N points dans le temps.
Maintenant, si vous avez une requête à des contacts et OU dans une période de temps (pas une date de rapport, mais une plage de dates), vous pourriez N multiplié par le nombre d'enregistrement si vous venez de faire un left join.
Ainsi, pour afficher l'unité d'organisation, vous avez besoin de simplement se joindre à la première unité d'organisation pour chaque contact.
Dans SQL server, vous pouvez utiliser de la croix-appliquer (ou plutôt de l'EXTÉRIEUR, car nous avons besoin d'une jointure gauche), qui va appeler une fonction table sur chaque ligne il a de rejoindre.
Dans PostgreSQL, à partir de la version 9.3, vous pouvez le faire aussi, il suffit d'utiliser la
LATERAL
mot-clé pour obtenir le même:OriginalL'auteur Stefan Steiger
Essayez d'utiliser une sous-requête dans votre clause. Un résumé exemple:
LIMIT 1
limiterait à une seule ligne sur le total. Mais nous avons besoin d'une ligne par"EsnId"
.Brandstetter: Correct, il manque le LATÉRALES mot clé. Si il avait écrit INNER JOIN LATÉRALES au lieu de simplement ADHÉRER, il serait de travailler (sur PG >= 9.3). Mais il devrait également avoir ajouté une ordonnance pour la LIMITE de 1.
OriginalL'auteur Dondi Michael Stroma