【问题标题】:Complexe SQL Query复杂的 SQL 查询
【发布时间】:2014-05-21 11:07:55
【问题描述】:

我有 3 张桌子:

Invoices(Invoice, InvoiceAmount(float), Other infos ...), table Payments(Payment, PaymentAmount(float), Other infos ...)和表 PaymentsDet(ID、发票、付款、金额(浮动))。 表 PaymentsDet 将发票和带有金额的付款(由该付款支付的发票部分)链接起来。

我需要一个查询来返回有关每张发票的信息 +

IF(该发票恰好有 1 笔付款)

付款、SUM(PayementsDet.Amount)、其他付款信息...

ELSE(超过 1 笔付款或根本不付款)

Count(Payment)、SUM(PayementsDet.Amount)NULL值或'' /strong>。

感谢您的宝贵时间,并希望有足够聪明的人可以帮助我。

编辑:

    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é

如果有人得到更好(更易读)的查询,我想我想通了。

【问题讨论】:

  • 您应该尽可能向我们展示您的查询,并告诉我们您遇到的问题,以便我们为您提供适当的提示如何完成它。

标签: sql report invoices


【解决方案1】:

因为您使用的是 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
));

【讨论】:

    【解决方案2】:

    感谢 Fares 付出的时间和精力。

    在我的案例中,问题不在于付款为 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 : Facture = Invoice 和 Règlement = Payment

    【讨论】:

    • 只是为了澄清我的逻辑,仔细查看 case 语句,如果发票只有一次付款,则返回 1,并返回 0 else(即当发票有零次或至少两次付款时),我使用的 10 并不表示付款次数,但我们必须将其视为布尔标志而不是计数器。
    • 感谢您的澄清,但在超过 2 笔付款的情况下,在 P.Payement 列中选择了一笔?
    • 但您在问题上说:ELSE(超过 1 笔付款或根本不付款)计数(付款)、总和(付款金额)、完成其他付款信息 NULL 值。
    • 是的,你是对的,除了一个小细节,在这种情况下我需要 COUNT(P.Payment) 而不是 P.Payement
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多