Je n'ai aucune idée du titre de cette question, je suis donc désolé si vous avez été induit en erreur par le titre. De plus, je suis désolé pour les noms de tables / colonnes en allemand, n'hésitez pas à demander si vous ne comprenez rien.
Je vais d'abord expliquer la partie pertinente de ma base de données:
Je dois essentiellement des tables: Termine
(rendez-vous) et Buchungen
(réservations). Un Termin peut avoir plusieurs Buchungen et un Buchung peut avoir plusieurs Termine (il s'agit donc d'une connexion n à n) . Ils sont connectés à la table TermineBuchungen
.
Le tableau Termine
a les colonnes Id
et Datum
(Date), le tableau Buchungen
a Id
et Bemerkung
(Annotation) et le tableau TermineBuchungen
(évidemment) a Termin
et Buchung
.
Pour avoir toutes les informations pertinentes sur un Buchung , j'ai besoin de l ' Id et du Bemerkung de celui-ci ainsi que de l' Termin Id et Datum du Termin concernant le Buchung qui a le Datum le plus élevé - c'est-à-dire le plus récent Résiliation concernant ce Buchung .
Ce que je veux maintenant, ce sont tous les Buchungen (c'est-à-dire toutes les informations pertinentes sur les Buchungen comme expliqué ci-dessus) qui sont connectés à un Termin spécifique. Cependant, ce Termin ne doit pas nécessairement être le Termin le plus récent des Buchungen - cela signifie que le Termin <(maximum) renvoyé / em> du Buchungen peut être un autre, que celui que j'ai recherché initialement.
Permettez-moi de vous expliquer cela à l'aide d'un exemple:
Termine:
Id Datum
0 1/1/2000
1 1/1/2001
2 1/1/2002
Buchungen:
Id Bemerkung
0 'a'
1 'b'
2 'c'
TermineBuchungne:
Termin Buchung
0 0
0 1
1 1
2 1
Maintenant, je veux toutes les informations pertinentes sur Buchung pour tous les Buchungen concernant Termin 0. Le résultat devrait ressembler à ceci:
Id Bemerkung NewestTermninId NewestTerminDatum
0 'a' 0 1/1/2000
1 'b' 1 1/1/2001
Le deuxième exemple est particulièrement intéressant, car le plus récent Termin ici n'est pas le Termin 0.
J'ai essayé de réaliser ceci comme ça:
SELECT
b.Id,
b.Bemerkung,
t.Id AS TerminId,
t.Datum AS TerminDatum
FROM Buchungen AS b
INNER JOIN TermineBuchungen AS tb ON b.Id = tb.Buchung
LEFT JOIN
(
SELECT t2.Id, t2.Datum
FROM Termine AS t2
INNER JOIN TermineBuchungen AS tb2 ON t2.Id = tb2.Termin AND tb2.Buchung = b.Id
WHERE t2.Datum =
(
SELECT MAX(t3.Datum)
FROM Termine AS t3
INNER JOIN TermineBuchungen AS tb3 ON t3.Id = tb3.Termin AND tb3.Buchung = b.Id
)
) AS t ON 1 = 1
WHERE tb.Termin = 1
Mais j'obtiens l'erreur L'identifiant en plusieurs parties "b.Id" est introuvable.
J'utilise un serveur MS SQL.
J'ai essayé de trouver une réponse à cette question pendant quelques heures maintenant, mais comme mentionné, je ne sais pas trop comment intituler ce problème.
3 réponses
Vous devriez pouvoir résoudre votre problème en utilisant APPLIQUER EXTERIEUR. OUTER
et CROSS APPLY
sont utilisés lorsque vous devez interroger des sous-requêtes corrélées, exactement comme dans votre cas:
SELECT
b.Id,
b.Bemerkung,
t.Id AS TerminId,
t.Datum AS TerminDatum
FROM Buchungen AS b
INNER JOIN TermineBuchungen AS tb ON b.Id = tb.Buchung
OUTER APPLY
(
SELECT t2.Id, t2.Datum
FROM Termine AS t2
INNER JOIN TermineBuchungen AS tb2 ON t2.Id = tb2.Termin AND tb2.Buchung = b.Id
WHERE t2.Datum =
(
SELECT MAX(t3.Datum)
FROM Termine AS t3
INNER JOIN TermineBuchungen AS tb3 ON t3.Id = tb3.Termin AND tb3.Buchung = b.Id
)
) AS t ON 1 = 1
WHERE tb.Termin = 1
Dans le fil de discussion que j'ai attaché à cette réponse, vous pouvez voir que votre cas est 3) Réutiliser un alias de colonne.
Requête plus simple, y compris des exemples de données:
-- sample data
;with Termine as (
select * from (values
(0, '2000-1-1'),
(1, '2001-1-1'),
(2, '2002-1-1')
) t(Id, Datum)
),
Buchungen as (
select * from (values
(0, 'a'),
(1, 'b'),
(2, 'c')
) t(Id, Bemerkung)
),
TermineBuchungen as (
select * from (values
(0, 0),
(0, 1),
(1, 1),
(2, 1)
) t(Termin, Buchung)
)
-- solution
select
Id,
Bemerkung,
TerminId,
TerminDatum
from (
select b.Id, b.Bemerkung, TerminId = t.Id, TerminDatum = t.Datum, MaxTerminDatum = max(t.Datum) over(partition by b.Id) from Buchungen b
join TermineBuchungen tb ON b.Id = tb.Buchung
join Termine t on t.Id = tb.Termin
) t
where TerminDatum = MaxTerminDatum
Il renvoie TerminId = 2 contrairement à votre exemple de résultat car TerminId = 2 est en effet lié à Buchung = 1 et il a la date la plus élevée.
Voici une autre solution:
SELECT
b.Id,
b.Bemerkung,
t.Id AS TerminId,
t.Datum AS TerminDatum
FROM Buchungen AS b
INNER JOIN TermineBuchungne AS tb ON b.Id = tb.Buchung
LEFT JOIN
(
SELECT t2.Id, t2.Datum, tb2.Buchung
FROM Termine AS t2
INNER JOIN TermineBuchungne AS tb2 ON t2.Id = tb2.Termin
WHERE t2.Datum =
(
SELECT MAX(t3.Datum)
FROM Termine AS t3
INNER JOIN TermineBuchungne AS tb3 ON t3.Id = tb3.Termin
INNER JOIN Buchungen b ON tb3.Buchung = b.Id
)
) AS t ON t.Buchung = b.Id
WHERE tb.Termin = 1
De nouvelles questions
sql
Le langage de requête structuré (SQL) est un langage permettant d'interroger des bases de données. Les questions doivent inclure des exemples de code, une structure de table, des exemples de données et une balise pour l'implémentation du SGBD (par exemple MySQL, PostgreSQL, Oracle, MS SQL Server, IBM DB2, etc.) utilisés. Si votre question concerne uniquement un SGBD spécifique (utilise des extensions / fonctionnalités spécifiques), utilisez plutôt la balise de ce SGBD. Les réponses aux questions marquées avec SQL doivent utiliser le standard SQL ISO / IEC.