以两种方式订购联接表的搜索

时间:2016-05-18 09:53:19

标签: php mysql sql

我正在尝试为每位客户搜索最早的未结发票,然后按照发票日期的降序显示结果,但结果会显示最新发票的日期。我怎样才能确保它获得最早的发票日期?非常感谢提前。

这是我的问题:

$checkDebtors = "select
    a.accountNumber as accountNumber, a.balanceOutstanding as balanceOutstanding, a.companyName as companyName, b.invoiceDate as invoiceDate, b.netOutstanding as netOutstanding
from
    customersQQuote a
    Right JOIN invoices b ON a.accountNumber = b.accountNumber
WHERE   netOutstanding > 0 AND balanceOutstanding > 0
group by
    a.accountNumber
order by
     b.invoiceDate ASC";

4 个答案:

答案 0 :(得分:0)

你的意思是跟随sql的结果吗?尝试一下,如果它不适合你,请给我发表评论;)

select
    a.accountNumber as accountNumber,
    a.balanceOutstanding as balanceOutstanding,
    a.companyName as companyName,
    b.invoiceDate as invoiceDate,
    c.netOutstanding as netOutstanding
from
    (SELECT accountNumber, MIN(invoiceDate) AS invoiceDate FROM invoices GROUP BY accountNumber) b
    LEFT JOIN customersQQuote a ON a.accountNumber = b.accountNumber
    LEFT JOIN invoices c ON c.accountNumber = b.accountNumber AND c.invoiceDate = b.invoiceDate
WHERE   c.netOutstanding > 0 AND a.balanceOutstanding > 0
group by
    a.accountNumber
order by
     b.invoiceDate ASC

答案 1 :(得分:0)

上面的代码有一些错误,例如在where子句中使用别名和使用group by子句。你可以申请这段代码..

select a.accountNumber as accountNumber, a.balanceOutstanding as balanceOutstanding,
a.companyName as companyName, b.invoiceDate as invoiceDate, b.netOutstanding as netOutstanding
from customersQQuote a Right JOIN invoices b ON a.accountNumber = b.accountNumber
WHERE b.netOutstanding > 0 AND a.balanceOutstanding > 0 order by b.invoiceDate;

答案 2 :(得分:0)

您当前的代码无效,因为您尚未指定要撤回的发票。您已使用GROUP BY accountNumber,因此它将为每个accountNumber值返回一行。其他字段应该是聚合值(即,诸如MIN()或MAX()之类的聚合函数的结果)。如果GROUP BY子句中既没有提到字段,也没有聚合函数的结果,那么MySQL将返回该列的值,但是没有定义该值来自哪一行。它可能是第一行或最后一行的值,或者介于两者之间(并且可能在不同版本的MySQL之间发生变化)。

大多数SQL都不允许这样的查询并且会出错。 MySQL有一个功能允许这样做。但是可以将此功能配置为关闭。

要在标准SQL中执行此操作并为您提供一致的值,请使用子查询来使用MIN()聚合函数获取每个accountNumber的第一个invoiceDate。然后,您将此子查询与发票表连接,以获取其他列。

SELECT a.accountNumber, 
        a.balanceOutstanding, 
        a.companyName, 
        b.invoiceDate, 
        b.netOutstanding
FROM
( 
    SELECT accountNumber, 
            MIN(invoiceDate) as invoiceDate
    FROM invoices
    GROUP BY accountNumber
) sub0
INNER JOIN invoices b ON sub0.account_number = b.account_number AND sub0.invoiceDate = b.invoiceDate
INNER JOIN customersQQuote a ON sub0.account_number = a.account_number

请注意,如果accountNumber可能有2个相同的first invoiceDate值,那么您需要选择另一个字段以最小化(即,可能是您的唯一ID字段)。变得凌乱但是像这样: -

SELECT a.accountNumber, 
        a.balanceOutstanding, 
        a.companyName, 
        b.invoiceDate, 
        b.netOutstanding
FROM
( 
    SELECT accountNumber, 
            MIN(invoiceDate) as invoiceDate
    FROM invoices
    GROUP BY accountNumber
) sub0
INNER JOIN
( 
    SELECT accountNumber, 
            invoiceDate,
            MIN(id) as id
    FROM invoices
    GROUP BY accountNumber, invoiceDate
) sub1 ON sub0.accountNumber = sub1.accountNumber AND sub0.invoiceDate = sub1.invoiceDate
INNER JOIN invoices b ON sub1.account_number = b.account_number AND sub1.invoiceDate = b.invoiceDate AND sub1.id = b.id
INNER JOIN customersQQuote a ON sub0.account_number = a.account_number

答案 3 :(得分:0)

感谢您的建议。我从你的答案中得到了一些很好的建议,帮助我解决了这个问题。最主要的是使用MIN()以及我使用Right join而不是Left。另外,我刚刚在ORDER BY中使用了invoiceDate关键字而不是b.invoiceDate。我想这确保了MIN规则也在这里使用。谢谢你,我最终得到了我需要的结果。

select
    a.accountNumber as accountNumber, a.balanceOutstanding as balanceOutstanding, a.companyName as companyName, MIN(b.invoiceDate) as invoiceDate, b.netOutstanding as netOutstanding
from
    customersQQuote a
    Left JOIN invoices b ON a.accountNumber = b.accountNumber
WHERE  netOutstanding > 0 AND balanceOutstanding > 0
group by
    a.accountNumber
order by invoiceDate ASC