PHP / SQL Group Rows and Sum Columns - mysql

I have a database where I need to group users together and then sum the invoice amount into a total. I just cannot seem to figure an elegant way of doing this, I tried iterating though a while loop using each usersID via an IF statement but this method would not be practical as each new user added later would require a new if statement to be added.
SQL Example
UserID Invoice InvoiceAMT
419 1 20.00
419 2 30.99
420 3 30.00
421 4 1.00
419 5 60.00
What I want to return is
UserID Total Invoices Total Amount
419 3 110.99
420 1 30.00
421 1 1.00

Use GROUP BY with SUM()
SELECT UserID, COUNT(Invoice) `Total Invoices`, SUM(InvoiceAMT) `Total Amount`
FROM table
GROUP BY UserID
Column names with spaces are bad so avoid them. For example instead of Total Invoices you should use TotalInvoices or Total_Invoices

Related

Delete the duplicate values in the SUM with MySQL or SQL

Hi I am doing a sum of a table, but the problem is that the table has duplicate rows, so I wonder how can I do the sum without duplicated rows:
The main table is this one:
folio
cashier_id
amount
date
0001
1
2500
2022-06-01 00:00:00
0002
2
10000
2022-06-01 00:00:00
0001
1
2500
2022-06-01 00:00:00
0003
1
1000
2022-06-01 00:00:00
If I sum that you can see that the first and the third row are duplicated, so when I do the sum it makes it wrong because, the result will be:
cashier_id
cash_amount
1
6000
2
10000
but it should be:
cashier_id
cash_amount
1
3500
2
10000
The query that I use to make the sum is this one:
SELECT `jysparki_jis`.`api_transactions`.`cashier_id` AS `cashier_id`,
SUM(`jysparki_jis`.`api_transactions`.`cash_amount`) AS `cash_amount`,,
COUNT(0) AS `ticket_number`,
DATE(`jysparki_jis`.`api_transactions`.`created_at`) AS `date`
FROM `jysparki_jis`.`api_transactions`
WHERE DATE(`jysparki_jis`.`api_transactions`.`created_at`) >= '2022-01-01'
AND (`jysparki_jis`.`api_transactions`.`dte_type_id` = 39
OR `jysparki_jis`.`api_transactions`.`dte_type_id` = 61)
AND `jysparki_jis`.`api_transactions`.`cashier_id` <> 0
GROUP BY `jysparki_jis`.`api_transactions`.`cashier_id`,
DATE(`jysparki_jis`.`api_transactions`.`created_at`)
How you can see the sum is this:
SUM(`jysparki_jis`.`api_transactions`.`cash_amount`).
I wonder how can I do the sum avoiding to duplicate the folio with same cashier_id?
I know that if I filter for the cashier_id and folio I can avoid the duplicate rows but I do not know how to do that, can you help me?
Thanks
Given your provided input tables, you can use the DISTINCT clause inside the SUM aggregation function to solve your problem:
SELECT cashier_id, SUM(DISTINCT amount)
FROM tab
GROUP BY cashier_id,
folio,
date
Check the demo here.
Then you can add up your conditions inside your WHERE clause to this query, and your aggregation on the "created_at" field (that should correspond to the "date" field of your sample table - I guess). This solution may give your the general idea.

Create a query to return number of produced products based on date in Microsoft Access

I want to create a query to get the total number of produced products for each day in Microsoft Access.
Here are the few rows of my table as a sample:the table's name is Orders
ordernumber number of products Date
100 2 11-May-16
101 1 11-May-16
121 2 24-May-16
122 3 24-May-16
131 1 25-May-16
105 3 11-May-16
127 1 24-May-16
135 2 25-May-16
The desired output is :
TotalNoProducts Date
6 11-May-16
6 24-May-16
3 25-May-16
This is one of the more basic aggregate queries:
SELECT SUM([number of products]) As TotalNoProducts, CDate(Int([Date])) As TheDate
FROM Orders
GROUP BY CDate(Int([Date]))
Note that you can also build this query through the query builder, which is usually easier for beginners than using SQL

MYSQL query - cross tab? Union? Join? Select? What should I be looking for?

Not sure what exactly it is I should be looking for, so I'm reaching out for help.
I have two tables that through queries I need to spit out one. the two tables are as follows:
Transactions:
TransactionID SiteID EmployeeName
520 2 Michael
521 3 Gene
TransactionResponse:
TransactionID PromptMessage Response PromptID
520 Enter Odometer 4500 14
520 Enter Vehicle ID 345 13
521 Enter Odometer 5427 14
521 Enter Vehicle ID 346 13
But what I need is the following, let's call it TransactionSummary:
TransactionID SiteID EmployeeName 'Odometer' 'VehicleID'
520 2 Michael 4500 345
521 3 Gene 5427 346
The "PromptID" column is the number version of "PromptMessage" so I could query off that if it's easier.
A good direction for what this query would be called is the least I'm hoping for. True extra credit for working examples or even using this provided example would be awesome!
For a predefined number of possible PromptID values you can use something like the following query:
SELECT t.TransactionID, t.SiteID, t.EmployeeName,
MAX(CASE WHEN PromptID = 13 THEN Response END) AS 'VehicleID',
MAX(CASE WHEN PromptID = 14 THEN Response END) AS 'Odometer'
FROM Transactions AS t
LEFT JOIN TransactionResponse AS tr
ON t.TransactionID = tr.TransactionID AND t.SiteID = tr.SiteID
GROUP BY t.TransactionID, t.SiteID, t.EmployeeName
The above query uses what is called conditional aggregation: a CASE expression is used within an aggregate function, so as to conditionally account for a subset of records within a group.

mysql query group function as a column

I need to write a query to calculate the sum of each account but the special thing that I want is to group the some of the debit of each month as a column.
So what I need is like this example:
SELECT accid "Account ID", Left(tr_date,7) "Date", SUM(debit) "Debit Sum"
FROM transactions
WHERE tr_date Between "2014-07-01" and "2014-09-30"
GROUP BY acc_id, LEFT(tr_date,7);
The result will be something like that:
Account ID Date Debit Sum
1111 2014-07 300
1111 2014-08 351
1111 2014-09 352
1123 2014-07 500
1123 2014-08 100
1123 2014-09 230
But what I was asked to have is the following result:
Account ID 2014-07 2014-08 2014-09
1111 300 351 352
1123 500 100 230
where the user chooses the dates so the number of the columns is not limited
is there any way to do this or no? thank you for any comment or answer.
The only way to do that is to know the dates beforehand.
SELECT accid "Account ID"
SUM(if(LEFT(tr_date,7)="2014-07",debit,0)) "2014-07"
SUM(if(LEFT(tr_date,7)="2014-08",debit,0)) "2014-09"
SUM(if(LEFT(tr_date,7)="2014-09",debit,0)) "2014-08"
FROM transactions
WHERE tr_date Between "2014-07-01" AND "2014-09-30"
GROUP BY acc_id
if you need the user to be able to choose or add columns, you'll need to build the query dinamically either with a stored procedure or another scripting language.
PD: you're treating your dates as strings and I kept that logic. It's not a good practice though

finding total and unique hits for each product

I have table structure as follows
id productid ip hittime
---------------------------------------------------------------------------
1 5 1.1.1.1 2011-05-03 06:55:11
2 5 1.1.1.1 2011-05-03 06:57:11
3 6 2.2.2.2 2011-05-03 07:30:00
4 4 1.1.1.1 2011-05-03 07:32:54
5 5 2.2.2.2 2011-05-03 07:55:00
Now I need query such that, it output me total and unique hits for each product
productid totalhits uniquehits
------------------------------------------------------------------
4 1 1
5 3 2
6 1 1
Criteria for
Total Hits = all the records that belong to particular product
Unique Hits = 2 hits are identified as unique hits if (1) IP is different or (2) for same ip, there is difference of 5 mins in hittime
How can I achieve this?
rMX was extremely close with his solution, it's quite clever. He should really get the credit, I just tweaked it slightly to add in a couple missing pieces:
select productid, count(*) totalhits,
count(distinct
concat(ip,
date_format(hittime, '%Y%m%d%H'),
round(date_format(hittime, '%i') / 5) * 5)
) uniquehits
from table
group by productid
Changes I made to rMX's idea:
Changed ceil() to round() because
ceil/floor will cause edge cases to
be treated improperly
Multiply the results of the round()
by 5. I think rMX meant to do this
and just forgot to type it.
EDIT: The multiplying by 5 really isn't necessary. My brain was just muddled. Changing ceil() to round() still matters though.
UPD>
select productid, count(*) totalhits,
count(distinct
concat(ip,
date_format(hittime, '%Y%m%d%H'),
ceil(date_format(hittime, '%i') / 5))
) uniquehits
from table
group by productid
I think, this should work. Sorry, had no time to test it.