I have a table in Postgresql called 'transaction'. The primary key of this table is composite with (id, date), where id is an int and date is a timestamp. Every day, the first order starts at order #1. The next order that day would be #2, then #3, and so on until the next day with #1 again.
I'm not sure how I would change this SQL query to find the max transaction ID specifically from today then increment 1 to it.. or start again at 1 if there are no transactions today. So far the only thing I can do is just start at 1 if there are no transactions at all, or increment based on the highest ID across all dates.
/* Insert Transaction */
bool dbmanager::addTransaction(const int& custPhone=0, const int& totalCents=0, const qstr& items="",
const qstr& paymentType="", const int& tender=0, const int& change=0,
const int& cardNum=0, const int& cardExp=0, const int& cardCVV=0, QWidget* from=nullptr)
{
QSqlQuery q;
// TODO: This query increments the largest order number that exists across all dates. Make it so the order number is 1 the max order number from today
q.prepare("insert into pos_schema.transaction values( (select ifnull(max(id), 0) 1 from pos_schema.transaction), NOW(), "
":phone, :total_cents, :items, :payment_type, :tender, :change, :card_number, :card_exp, :card_cvv);");
q.bindValue(":phone",custPhone);
q.bindValue(":total_cents", totalCents);
q.bindValue(":items", items);
q.bindValue(":payment_type", paymentType);
q.bindValue(":tender", tender);
q.bindValue(":change", change);
QString cryptCardNum = crypt.encryptToString(qstr::number(cardNum));
QString cryptCardExp = crypt.encryptToString(qstr::number(cardExp));
QString cryptCardCVV = crypt.encryptToString(qstr::number(cardCVV));
q.bindValue(":card_number", cryptCardNum);
q.bindValue(":card_exp", cryptCardExp);
q.bindValue(":card_cvv", cryptCardCVV);
if (q.exec())
return true;
qDebug() << "Transaction Insertion Error:" << q.lastError().text();
displayError("Insertion", from, q);
return false;
}
CodePudding user response:
You need to update your sub-select
select ifnull(max(id), 0) 1 from pos_schema.transaction
to something like
SELECT
ifnull(max(id), 0) 1
FROM pos_schema.transaction
WHERE
pos_schema.transactiondate.date::date = CURRENT_DATE
Please note that your field date
should really be of type date
instead of timestamp
. Otherwise your primary key does not protect you from inserting two duplicate IDs for the same date if they have different timestamps.