Find highest value in column using ANY or ALL - sql

I'm new to SQL and am currently learning and this is probably a fairly basic question:
I have 4 tables
1) Customer (customerName, street, customerCity)
2) Deposit (customerName, branchName, accountNumber, balance)
3) Loan (customerName, branchName, loanNumber, amount)
4) Branch (branchName, branchCity, assets)
Each table has some data inserted into it.
I have been asked to find the customerName with the highest deposit amount. (So I'm guessing I will be using just the Deposit table)?
However, here is the catch, the sheet I am learning from is requesting that I MUST use either ALL or ANY, I can't simply use the MAX function to achieve this.
How would I achieve this? I've tried query after query and simply can't find a way to get it to work (baring in mind that I've only been learning this for a week).
The things I've been trying have been along the lines of:
SELECT customerName
FROM Deposit
WHERE balance > ALL;
The query should return 1 value, which would be the customerName with the highest balance value.
Thanks a lot for you help :)!

You are looking for the customer(s) whose balance is greater than or equal to all balances in the table
so you just need to use >= instead of >
SELECT customerName
FROM Deposit
WHERE balance >= ALL (SELECT balance
FROM Deposit);
Or you can use a correlated sub query and look for customers whose balances are greater than all other balance values.
SELECT customerName
FROM Deposit d1
WHERE balance > ALL (SELECT balance
FROM Deposit d2
WHERE d2.balance <> d1.balance);
In the event of ties both queries will return all customers with the highest amount.

Related

How do I make an SQL query in Postgres that finds total balance and applies credit fees for the year?

I am totally new to Postgres and I cant find any example of what I am trying to do...
I have a table of transactions for a year:
amount | date
12 | 1980-02-12
-200 | 1980-03-06
30 | 1980-03-14
Positive transactions for incoming money.
Negative transactions for credit payments.
And I need to return a total for the year that also reflects charging a $20 fee for every month where less than $400 in credit was used, like so:
total
-------
80,401
My thought was that I would first find total credit for all months like this...
WITH month_credit_totals
AS
(SELECT
SUM(amount) AS total_credit
FROM transactions
WHERE amount < 0
GROUP BY DATE_TRUNC('month', date))
and from there I would find the amount of months with less than $400 in credit payments like this...
SELECT
COUNT(*)
FROM month_credit_totals
WHERE total_credit <= -400
I wanted to save off this number, subtract it from 12, multiply that result by -20, and get the total amount owed in credit fees for the year that way.
Then, I thought I could just total up the amount column, apply that total fee amount, and that would be my result.
But I am having so much trouble understanding the syntax as a complete beginner, I cant find a way to save off variables, do the math, and apply that to total. I am constantly getting syntax errors that are pointing me in no direction just when I try to declare a variable at all.
Maybe I'm going about this the completely wrong way?
I would appreciate any advice. Thanks!
You're on the right track, but you don't really need to save these variables anywhere, just calculate it on the fly.
WITH credit_by_month AS
(
SELECT DATE_TRUNC('month', dt), SUM(amount) AS total_credit
FROM transactions
WHERE amount < 0
GROUP BY DATE_TRUNC('month', dt)
)
SELECT COUNT(*) * 20 AS credit_fee
FROM credit_by_month
WHERE total_credit > -400
Here's a working demo on dbfiddle, it's using random data so it will return a different number every time.

PostgreSQL question - finding sum of sales by state

I need help writing the query, we have a table called SALES, which has 3 columns as below:
Column Names: sale_id, state, sale_amount_cents
I assume the sale_amount_cents has the sale amount in cents as opposed to dollars, and our end answer needs to be in dollars so we would have to multiply by 100.
Can someone please help writing the query to sum sales, in dollars, by date, rounding to two decimal places, and sorting from the greatest sale amount to the least?
I assume the query would look like this:
UPDATE SALES SET sale_amount_cents=sale_amount_cents*100
SELECT SUM(sale_amount_cents) from SALES
GROUP BY STATE
ORDER BY sale_amount_cents DESC;
select state, SUM(sale_amount_cents)/100 as Sales_in_dollar from SALES
GROUP BY STATE ORDER BY SUM(sale_amount_cents) DESC

SUM rows by column unknown parameter - SQL

I've a table like this one
Where each customer has its own budget, and he/she spent it on some fruits. Budget isn't deduplicated by row (so Mike has 20 bucks to spend overall), whilst spent budget is purchase-specific (Mike has now 1 dollar to spend only)
I'd like to add a column that sum the overall spend by each customer in a non deduplicated way.
Like this:
I can't specify any WHERE clause, as I don't know all the names of the customers.
Any idea on how to go from one table to the other?
Thanks,
Carlo
You could use this query to achieve the data you need:
select
customer_name,
customer_budget,
purchase_type,
budget,
customer_budget - sum(budget) as remaining_budget
from Customers
group by customer_name, customer_budget, purchase_type, budget
Hope this helps :)

How to achieve mathematical expression in postgres SQL query?

I have a kind of requirement to find out "Main Balance" from a PostgreSQL database table.
Here, The Logic is pretty much easy likewise,
Main Balance = Credit + Refund - Debit
I have a database table likewise,
Table Name :- Account
Columns :- id, source_account_number, destination_account_number, transaction_type, amount, creation_date_time
Here, transaction_type could have following set of possible values, CREDIT, REFUND, DEBIT.
Now, I would like to know for example what's my A/c balance then logic should be likewise,
Main Balance = sum of all CREDIT entries + sum of all REFUND entries -
sum of all DEBIT entries.
So Basically, I am trying to achieve this through a single query.
For example(I know it's wrong but still let me paint),
select sum(amount) from Account where destination_account_number = 'XYZ' and transaction_type in ('CREDIT', 'REFUND');
But It'll return only deposited amount itself, what about DEBIT.
Obviously we can recover those as well but it's promoting for multiple query.
Can Anyone help me to do this through easiest, optimised way to achieve this functionality ?
Any help will really appreciable to all those who will show their interest !!
UPDATE -
Here, transaction_type could have following set of possible values, CREDIT, REFUND, DEBIT, OTHERS, PENDING, EXPIRED.
Now, Please consider Main Balance logic :- CREDIT + REFUND - DEBIT where PENDING, EXPIRED Money will be skipped in a main-balance calculation.
This can be done with conditional aggregation.
select sum(case when transaction_type in ('CREDIT', 'REFUND') then amount else -amount end)
from Account
where destination_account_number = 'XYZ'

select distinct records

I have a table like as shown above. As you can see that value in the "v_ctra_no" column repeats. What type of sql query should I use so that I am able to select those rows whose "v_ctra_no" value is unique. Like for example
col_name1 col_name2 col_name3
Ctra#001 Cash 200
Ctra#002 Sales 40
Ctra#003 Purchase 1000
I tried to use the query mentioned below but it does not work
SELECT DISTINCT(v_ctra_no),v_ctra_date,v_ctra_id FROM TBL_ACC_CTRA_VCH_MSB
It looks like you're trying to sum up the sales amounts. Seems that this is more what you are looking for:
SELECT v_ctra_no, v_ctra_dr_ledgeacc_name, SUM(v_ctra_dr_ledgeacc_amt) AS v_total_sales
FROM TBL_ACC_CTRA_VCH_MSB
GROUP BY v_ctra_no, v_ctra_dr_ledgeacc_name
This will show the account number and account name, along with the total (SUM) of all of the entries in the account amount column. As long as the account name is the same for all of the account number entries, then you won't have any duplicates.
However, you may want to consider restructuring your database (if you have that option), so that account details are separate to the separate sales amounts.
If you don't want the sales information and just want the account details along with the dates, then you can do a distinct on the name like this:
SELECT DISTINCT v_ctra_no, v_ctra_date
FROM TBL_ACC_CTRA_VCH_MSB
However, you will get duplicates for each time the date is different but the account number stays the same. If you think about it for a bit, it makes sense.
If you just want the distinct account numbers, then just use:
SELECT DISTINCT v_ctra_no
FROM TBL_ACC_CTRA_VCH_MSB