Сложный SQL-запрос

У меня есть 3 таблицы:

Таблица Счета(Счет, Сумма счета(плавающая), Другая информация...), таблица Платежи(Платеж, Сумма платежа(плавающая), Другая информация...) и таблица < strong>PaymentsDet(Id, Invoice, Payment, Amount(float)). Таблица PaymentsDet связывает счет-фактуру и платеж с суммой (частью счета-фактуры, оплаченной этим платежом).

Мне нужен запрос, возвращающий информацию о каждом счете +

ЕСЛИ (по этому счету есть ровно 1 платеж)

Платеж,СУММА(PayementsDet.Amount), другая информация о платеже...

ИНАЧЕ (более 1 платежа или отсутствие платежа)

Count(Payment), SUM(PayementsDet.Amount), Complete other Payment info со значениями NULL или '' .

Спасибо за ваше время, и надеюсь, что есть кто-то достаточно умный, который может помочь мне в этом.

РЕДАКТИРОВАТЬ :

    SELECT        Factures.Facture, Factures.Client, Factures.DateFacture, Factures.MoisFacture, Factures.DateRéception, Factures.Echéance, Factures.Montant, Factures.TxTVA, 
                         Factures.Activité,
                             (SELECT        CASE WHEN SUM(Montant) IS NULL THEN '0' ELSE SUM(Montant) END AS Expr1
                               FROM            RèglementsDet
                               WHERE        (Facture = Factures.Facture) AND (Validé = 1)) AS MontantRegl,
                             (SELECT        CASE WHEN COUNT(DISTINCT Règlements.Règlement) > '1' THEN COUNT(DISTINCT Règlements.Règlement) 
                                                         WHEN COUNT(DISTINCT Règlements.Règlement) = '1' THEN
                                                             (SELECT        MIN(Règlements.Règlement) AS Expr1
                                                               FROM            Règlements INNER JOIN
                                                                                         RèglementsDet ON Règlements.Règlement = RèglementsDet.Règlement
                                                               WHERE        (RèglementsDet.Facture = Factures.Facture)) END AS Règlement
                               FROM            Règlements INNER JOIN
                                                         RèglementsDet AS RèglementsDet_2 ON Règlements.Règlement = RèglementsDet_2.Règlement
                               WHERE        (RèglementsDet_2.Facture = Factures.Facture) AND (RèglementsDet_2.Validé = 1)) AS Règlement
FROM            Factures LEFT OUTER JOIN
                         RèglementsDet AS RèglementsDet_1 ON Factures.Facture = RèglementsDet_1.Facture
GROUP BY Factures.Facture, Factures.Client, Factures.DateFacture, Factures.MoisFacture, Factures.DateRéception, Factures.Echéance, Factures.Montant, Factures.TxTVA, 
                         Factures.Activité

Я думаю, что понял это, если у кого-то есть лучший (более читаемый) запрос.


person Ismail Karchi    schedule 21.05.2014    source источник
comment
Вы должны показать нам свой запрос до конца и сообщить нам, где вы застряли, чтобы мы могли дать вам соответствующую подсказку, как выполнить его.   -  person Thorsten Kettner    schedule 21.05.2014


Ответы (2)


Поскольку вы используете оператор CASE, я думаю, вы должны легко понять этот SQL-запрос и настроить имена на имена ваших полей:

(SELECT P.Payement,SUM(D.Amount), P.CreatedAt, P.Expired FROM Invoices I, Payements P, PayementsDet D WHERE 1 = (
    SELECT(
             CASE 
                  WHEN (SELECT count(D.Payement) FROM Invoices I, Payements P WHERE ( D.Invoice = I.Invoice AND P.Payement = D.Payement ) GROUP BY I.Invoice) = 1 
                     THEN 1 
                  ELSE 0 
             END)
    FROM  Invoices I, Payements P, PayementsDet D
))
UNION
(SELECT P.Payement,SUM(D.Amount), null, null FROM Invoices I, Payements P, PayementsDet D WHERE 0 = (
    SELECT(
             CASE 
                  WHEN (SELECT count(D.Payement) FROM Invoices I, Payements P WHERE ( D.Invoice = I.Invoice AND P.Payement = D.Payement ) GROUP BY I.Invoice) = 1 
                     THEN 1 
                  ELSE 0 
             END)
    FROM  Invoices I, Payements P, PayementsDet D
));

Схема базы данных

person Fares M.    schedule 21.05.2014

Спасибо, Фарес, за ваше время и усилия.

Проблема в моем случае заключалась не в том, что есть 1 или 0 платежей, а в том, что я получил несколько платежей по одному и тому же счету. Наконец-то я понял, как это сделать, даже если это довольно сложно, но вот решение, которое я нашел, надеюсь, оно поможет кому-то еще.

SELECT        Factures.Facture, Factures.Client AS [Code C/F], Factures.DateFacture, Factures.MoisFacture, Factures.DateRéception, Factures.Echéance, Factures.Montant, 
                         Factures.TxTVA, Factures.Activité,
                             (SELECT        CASE WHEN SUM(Montant) IS NULL THEN '0' ELSE SUM(Montant) END AS Expr1
                               FROM            RèglementsDet
                               WHERE        (Facture = Factures.Facture) AND (Validé = 1)) AS MontantRegl,
                             (SELECT        CASE WHEN COUNT(DISTINCT Règlements.Règlement) > '1' THEN COUNT(DISTINCT Règlements.Règlement) 
                                                         WHEN COUNT(DISTINCT Règlements.Règlement) = '1' THEN
                                                             (SELECT        MIN(Règlements.Règlement) AS Expr1
                                                               FROM            Règlements INNER JOIN
                                                                                         RèglementsDet ON Règlements.Règlement = RèglementsDet.Règlement
                                                               WHERE        (RèglementsDet.Facture = Factures.Facture)) END AS Règlement
                               FROM            Règlements INNER JOIN
                                                         RèglementsDet AS RèglementsDet_2 ON Règlements.Règlement = RèglementsDet_2.Règlement
                               WHERE        (RèglementsDet_2.Facture = Factures.Facture) AND (RèglementsDet_2.Validé = 1)) AS Règlement,
                             (SELECT        CASE WHEN COUNT(DISTINCT Règlements_1.Règlement) = '1' THEN
                                                             (SELECT        TOP (1) Règlements.Banque AS Expr1
                                                               FROM            Règlements INNER JOIN
                                                                                         RèglementsDet ON Règlements.Règlement = RèglementsDet.Règlement
                                                               WHERE        (RèglementsDet.Facture = Factures.Facture)) ELSE '' END AS Expr1
                               FROM            Règlements AS Règlements_1 INNER JOIN
                                                         RèglementsDet AS RèglementsDet_2 ON Règlements_1.Règlement = RèglementsDet_2.Règlement
                               WHERE        (RèglementsDet_2.Facture = Factures.Facture) AND (RèglementsDet_2.Validé = 1)) AS Banque,
                             (SELECT        CASE WHEN COUNT(DISTINCT Règlements_1.Règlement) = '1' THEN
                                                             (SELECT        TOP (1) Règlements.ModeDeRèglement AS Expr1
                                                               FROM            Règlements INNER JOIN
                                                                                         RèglementsDet ON Règlements.Règlement = RèglementsDet.Règlement
                                                               WHERE        (RèglementsDet.Facture = Factures.Facture)) ELSE '' END AS Expr1
                               FROM            Règlements AS Règlements_1 INNER JOIN
                                                         RèglementsDet AS RèglementsDet_2 ON Règlements_1.Règlement = RèglementsDet_2.Règlement
                               WHERE        (RèglementsDet_2.Facture = Factures.Facture) AND (RèglementsDet_2.Validé = 1)) AS ModeRegl,
                             (SELECT        CASE WHEN COUNT(DISTINCT Règlements_1.Règlement) = '1' THEN
                                                             (SELECT        TOP (1) Règlements.NumDocument AS Expr1
                                                               FROM            Règlements INNER JOIN
                                                                                         RèglementsDet ON Règlements.Règlement = RèglementsDet.Règlement
                                                               WHERE        (RèglementsDet.Facture = Factures.Facture)) ELSE '' END AS Expr1
                               FROM            Règlements AS Règlements_1 INNER JOIN
                                                         RèglementsDet AS RèglementsDet_2 ON Règlements_1.Règlement = RèglementsDet_2.Règlement
                               WHERE        (RèglementsDet_2.Facture = Factures.Facture) AND (RèglementsDet_2.Validé = 1)) AS NumDocument,
                             (SELECT        CASE WHEN COUNT(DISTINCT Règlements_1.Règlement) = '1' THEN
                                                             (SELECT        TOP (1) Règlements.DateRèglement AS Expr1
                                                               FROM            Règlements INNER JOIN
                                                                                         RèglementsDet ON Règlements.Règlement = RèglementsDet.Règlement
                                                               WHERE        (RèglementsDet.Facture = Factures.Facture)) ELSE NULL END AS Expr1
                               FROM            Règlements AS Règlements_1 INNER JOIN
                                                         RèglementsDet AS RèglementsDet_2 ON Règlements_1.Règlement = RèglementsDet_2.Règlement
                               WHERE        (RèglementsDet_2.Facture = Factures.Facture) AND (RèglementsDet_2.Validé = 1)) AS DateRèglement, Factures.Montant -
                             (SELECT        CASE WHEN SUM(Montant) IS NULL THEN '0' ELSE SUM(Montant) END AS Expr1
                               FROM            RèglementsDet AS RèglementsDet_3
                               WHERE        (Facture = Factures.Facture) AND (Validé = 1)) AS Solde
FROM            Factures LEFT OUTER JOIN
                         RèglementsDet AS RèglementsDet_1 ON Factures.Facture = RèglementsDet_1.Facture
GROUP BY Factures.Facture, Factures.Client, Factures.DateFacture, Factures.MoisFacture, Factures.DateRéception, Factures.Echéance, Factures.Montant, Factures.TxTVA, 
                         Factures.Activité

P.S. Фактура = Счет-фактура и Регламент = Оплата

person Ismail Karchi    schedule 22.05.2014
comment
Просто чтобы прояснить мою логику, внимательно посмотрите на оператор case, он возвращает 1, если в счете ровно один платеж, и возвращает 0 в противном случае (т.е. . когда счет содержит ноль или по крайней мере два платежа), 1 и 0, которые я использовал, не означают количество платежей, но мы должны принять его как логический флаг и не как счетчик. - person Fares M.; 22.05.2014
comment
Спасибо за разъяснение, но в случае более 2-х платежей, какой из них выбран в графе P.Payement? - person Ismail Karchi; 23.05.2014
comment
Но вы ответили на свой вопрос: ELSE (более 1 платежа или вообще без платежа) Count(Payement), SUM(PayementsDet.Amount), заполните другую информацию о платеже с NULL ценности. - person Fares M.; 23.05.2014
comment
Да, вы правы, за исключением одной маленькой детали, в этом случае мне нужно COUNT(P.Payment), а не P.Payment. - person Ismail Karchi; 23.05.2014