Синтаксис вложенного запроса MySQL INSERT / SELECT - PullRequest
1 голос
/ 02 февраля 2011

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

mysql_query("INSERT INTO donations(
            tid,
            email,
            amount,
            ogrequest,
            total
            )
            VALUES (
                '".esc($p->ipn_data['txn_id'])."',
                '".esc($p->ipn_data['pay_email'])."',
                ".(float)$amount.",
                '".esc(http_build_query($_POST))."',

            Here I want to select the row with the max date, get the value of the "total" column in that row, and add $amount to that value to form the new "total" for my newly inserted row.

            )");

Кто-нибудь может помочь братану?

Ответы [ 4 ]

3 голосов
/ 02 февраля 2011

Реальный ответ: вы не должны хранить сумму в столбце этой таблицы.Это не очень полезная информация.То, что вы должны хранить, это текущая дата, а затем вычисление суммы с помощью SUM и GROUP BY.Если это то, к чему вам нужно часто обращаться, то кэшируйте значение в другом месте.

Зачем вам нужно итоговое значение в любой из строк до последней?Это просто потраченные впустую данные, и их можно легко восстановить из таблицы.

Почему вы хотите сохранить сумму в этом столбце.Какое значение эти данные добавляют к вашей схеме?Здесь важно отметить, что сумма НЕ является свойством отдельной транзакции.Итоговое значение является свойством агрегированного подмножества отдельных транзакций.

Кроме того, убедитесь, что вы используете DECIMAL, а не FLOAT для типов денежных столбцов в MySQL, если это не так.Значения FLOAT могут привести к ошибкам округления в зависимости от того, что вы делаете, и это не повод для риска, когда речь идет о деньгах.

0 голосов
/ 02 февраля 2011
mysql_query("INSERT INTO donations(
            tid,
            email,
            amount,
            ogrequest,
            total
            )
            VALUES (
                '".esc($p->ipn_data['txn_id'])."',
                '".esc($p->ipn_data['pay_email'])."',
                ".(float)$amount.",
                '".esc(http_build_query($_POST))."',
                (select max(total) from donations) + ".(float)$amount."




            )");
0 голосов
/ 02 февраля 2011

Ваш подзапрос может выглядеть так:

SELECT total
FROM donations 
WHERE tid = <x>
ORDER BY date DESC
LIMIT 1

Это, конечно, требует, чтобы в вашей таблице был столбец date. Если вы запустите этот (без внешнего запроса, который у вас уже есть), он должен вернуться с одной строкой, результатом в один столбец, содержащим значение последней суммы для tid = .

Если в таблице еще нет строки для txn = , то она, очевидно, вообще не вернет строку. При использовании в качестве подзапроса для оператора INSERT вам, вероятно, следует проверить NULL и заменить его числовым 0 (ноль). Вот что IFNULL () может сделать для вас.

Объединяя это и то, что у вас уже есть:

mysql_query("INSERT INTO donations(
            tid,
            email,
            amount,
            ogrequest,
            total
            )
            VALUES (
                '".esc($p->ipn_data['txn_id'])."',
                '".esc($p->ipn_data['pay_email'])."',
                ".(float)$amount.",
                '".esc(http_build_query($_POST))."',
                IFNULL(SELECT total
                 FROM donations
                 WHERE id = ".esc(p->ipn_data[txn_id']."
                 ORDER BY date DESC 
                 LIMIT 1),0) + ".esc($p->ipn_data['value']
            )");
0 голосов
/ 02 февраля 2011

У меня нет доступа к серверу MySQL, чтобы проверить, что я создал, но попробуйте это:

INSERT INTO donations
(
    tid,
    email,
    amount,
    ogrequest,
    total
)
SELECT
    '".esc($p->ipn_data['txn_id'])."',
    '".esc($p->ipn_data['pay_email'])."',
    ".(float)$amount.",
    '".esc(http_build_query($_POST))."',
    total + '".esc($amount)."'
FROM
ORDER BY date DESC
LIMIT 1

Вместо использования прямого "INSERT INTO (...) VALUES (...)) "Я использовал" INSERT INTO (...) SELECT ... ".Оператор SELECT извлекает строку с самой высокой датой (ORDER BY date DESC LIMIT 1), затем к полному итогу осуществляется доступ и добавляется значение $ amount.

...