Existem 3 tabelas simples Orders, OrderLines e OrderLineRealizations com relacionamentos óbvios. Quero retornar algumas informações sobre orders com uma coluna adicional que representa a existência de uma realização de qualquer linha para um determinado grupo.
A consulta simplificada se parece com isto:
SELECT
Orders.Id,
SUM(OrderLines.Quantity) AS TotalAmount,
-- Is there a realization?
FROM Orders
INNER JOIN OrderLines ON OrderId = Orders.Id
GROUP BY Orders.Id -- some additional grouping
Tentei:
SELECT
Orders.Id,
SUM(OrderLines.Quantity) AS TotalAmount,
CASE
WHEN EXISTS (SELECT * FROM OrderLineRealizations
WHERE OrderLineId IN (OrderLines.Id))
THEN 1
ELSE 0
END AS RealizationExists
FROM Orders
INNER JOIN OrderLines ON OrderId = Orders.Id
GROUP BY Orders.Id
Mas não é permitido usar IN assim. Eu também não posso usar Left Join para realizações, porque então eu obtenho um TotalAmount incorreto.
Resultado que desejo alcançar:
Orders
- - - -
Id
1
2
OrderLines
- - - -
Id | OrderId | Quantity
1 | 1 | 10
2 | 1 | 15
3 | 2 | 11
OrderLineRealizations
- - - -
Id | OrderLineId |
1 | 1 |
Result
- - - -
OrderId | TotalAmount | RealizationExists
1 | 25 | 1
2 | 11 | 0
Como posso escrever uma consulta para obter o resultado esperado?
Aqui está a demonstração do DBFiddle
A maneira segura é
GROUP BY
agregar em uma tabela derivada antes de unir:Demonstração: https://dbfiddle.uk/8yejSpeu (baseado no violino de @Cetin Basoz, obrigado!)
Inspirado pela solução de Cetin Bazos, encontrei outra solução mais simples:
https://dbfiddle.uk/rIgDBBKa
A resposta acima de @GeorgeKarlinzer funciona. Acho que a confusão vem do fato de que a tabela Orderlines não tem uma coluna orderline.
= = =
O exemplo abaixo foi testado no dbfiddle.uk conforme a dica do @Cetin Basoz - Obrigado.
https://dbfiddle.uk/0uSTqI6H