2016-05-18 1 views
2

Я пытаюсь найти самую старую непогашенную сумму счета для каждого клиента, а затем представить результаты в порядке убывания этой даты счета, однако результат дает мне дату самого последнего счета-фактуры. Как я могу обеспечить, чтобы он собирал самую раннюю дату счета? Спасибо заранее.Порядок поиска объединенных таблиц двумя способами

Вот мой запрос:

$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"; 

ответ

0

Благодарим вас за советы. Я получил несколько полезных советов от ваших ответов, которые помогли мне решить проблему. Главное - использование MIN(), а также то, что я использовал Right join, а не Left. Кроме того, я просто использовал ключевое слово invoiceDate в ORDER BY, а не 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 
+0

Обратите внимание, что этот SQL-запрос по-прежнему будет возвращать, возможно, неправильную netOutstanding. Если у клиента есть несколько невыполненных счетов-фактур, то вы указали, что хотите получить первую дату счета, но какая netOutstanding возвращается, не указана и может появляться из любой строки.Это основная проблема, с которой столкнулся ваш оригинальный SQL. – Kickstart

+0

Далее, поскольку вы проверяете значение netOutstanding в предложении WHERE, которое исходит из таблицы счетов-фактур, вы фактически сделали INNER JOIN, а не LEFT OUTER JOIN. – Kickstart

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 
+0

Thanks Reno, это дало мне правильный порядок в результатах и ​​правильных счетах, но это дало мне 11 из 212 результатов. Я думаю, что тот факт, что он просматривал счета-фактуры, сначала может перейти к следующему клиенту, прежде чем найти netOutsanding> 0. Однако я получил то, что мне было нужно от вас. –

0

Приведенный выше код имеет определенные ошибки, такие как, имя псевдонима, используя в котором положение и злоупотребление группы по п. вы можете применить этот фрагмент кода.

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; 
0

Ваш текущий код не работает, поскольку вы не указали, какой счет-фактуру нужно отменить. Вы использовали GROUP BY accountNumber, поэтому он будет возвращать одну строку для каждого значения accountNumber. Другие поля должны быть агрегированными значениями (т. Е. Результатом совокупной функции, такой как MIN() или MAX()). Если поля не упоминаются в предложении GROUP BY или результат агрегатной функции, тогда MySQL вернет значение для этого столбца, но какая строка, из которой происходит это значение, не определена. Это может быть первое или последнее значение строки или любое промежуточное (и может меняться между различными версиями MySQL).

Большинство вариантов SQL не допускают такой запрос и будут ошибки. У MySQL есть функция, которая позволяет это. Но эту функцию можно настроить для отключения.

Чтобы сделать это в стандартном SQL и дать вам согласованное значение, вы используете вспомогательный запрос, чтобы получить первый счет-фактуру для каждого номера учетной записи, используя функцию агрегации MIN(). Затем вы присоединяете этот вспомогательный запрос к таблице счетов-фактур, чтобы получить другие столбцы.

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 одинаковые значения первого 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 
( 
    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 
+0

Спасибо за подробный ответ и объяснение Kickstart, к сожалению, это дало мне 648 результатов из ожидаемого 212. В него вошли клиенты, у которых баланс остался равен 0. Я решил проблему и ответил на нее выше. –

+0

@NickDale - если вы можете опубликовать некоторые образцы данных, я сортирую проблему. Тривиально добавить предложение WHERE, чтобы проверить значение netOutstanding. – Kickstart

Смежные вопросы