I have two table as
Country table
id name
1 Nepal
2 India
Salary Table
id Countryid termid amount
1 1 1 100
1 1 2 500
3 2 1 200
4 2 2 400
i want result as
CountryName basicSalary allowance
Nepal 100 500
India 200 400
Here term 1 is basic salary and 2 is allowance
You can try the below query
SELECT c.name,
SUM(CASE WHEN s.termid = 1 THEN amount ELSE 0 END) basicSalary,
SUM(CASE WHEN s.termid = 2 THEN amount ELSE 0 END) allowance
FROM Country c
JOIN Salary s on c.id = s.Countryid
GROUP BY c.name;
Hope this would help you out.
Just join the table twice (use aliases)
select c.name as CountryName,
s1.amount as basicSalary
s2.amount as allowance
from Country c
left join Salary s1
on s1.countryid=c.id
and s1.termid = 1
left join Salary s2
on s2.countryid=c.id
and s2.termid = 2
Related
I have a table named deposit, below
dep_id
deposit_amount
comp_id
1
100
1
2
100
1
3
100
1
When I run the query below I get the next updated table which is not what I want :
query = em.createNativeQuery("UPDATE deposit SET deposit_amount = (SELECT SUM(deposit_amount) - 50) WHERE comp_id = :comp_id");
query.setParameter("comp_id", comp_id);
The updated table after the above query
dep_id
deposit_amount
comp_id
1
50
1
2
50
1
3
50
1
But I want when I substract 50 or any amount it should get the sum of the columns and minus the amount from the sum not from each column. Below
dep_id
deposit_amount
comp_id
1
83.3
1
2
83.3
1
3
83.3
1
Because the sum is 300, and 300-50 = 250
Please how should I do this?
Using a common table expression, you can use this query. Get the total deposit amount per comp_id. Then join this new table (called total) to deposit on comp_id. Subtract 50 from the sum.
WITH total as(
select comp_id,
sum(deposit_amount) as total
from
deposit
group by
comp_id
)
select dep.dep_id,
ttl.total - 50 as deposit_amount,
dep.comp_id
from
deposit dep
inner join
total ttl
on
dep.comp_id = ttl.comp_id
Sample:
dep_id
deposit_amount
comp_id
1
250
1
2
250
1
3
250
1
You should compute deposit amount in a separate query, then join back your two tables on matching "comp_id" value
WITH cte AS (
SELECT DISTINCT comp_id,
SUM(deposit_amount) OVER(PARTITION BY comp_id) AS amount
FROM deposit
)
UPDATE deposit
INNER JOIN cte
ON deposit.comp_id = cte.comp_id
SET deposit_amount = cte.amount - 50
WHERE deposit.comp_id = :comp_id;
In your final query it should look like:
query = em.createNativeQuery("WITH cte AS (SELECT DISTINCT comp_id, SUM(deposit_amount) OVER(PARTITION BY comp_id) AS amount FROM deposit) UPDATE deposit INNER JOIN cte ON deposit.comp_id = cte.comp_id SET deposit_amount = cte.amount - 50 WHERE deposit.comp_id = :comp_id");
query.setParameter("comp_id", comp_id);
Check the demo here.
I have three database tables ‘customer’, ‘billing’, and ‘transaction’
customer:
cuid
name
address
1
David
City 1
2
Roja
City 2
billing :
id
cuid
month
bill_amount
1
1
1
100
2
1
2
200
3
2
1
400
4
1
3
100
transaction:
id
cuid
date
received_amount
1
1
2022-3-02
250
2
2
2022-2-02
200
3
2
2022-3-02
200
I need a new generated Due table after calculating month wise due amount using FIFO like this:
cuid
Name
Address
Month
Due_Amount
1
David
City 1
2
50
1
David
City 1
3
100
This code did not work properly. MySql Code:
SELECT
due.cuid,
due.Name,
due.Address,
due.Month,
sum(due.Amount - due.Received) AS Due_Amount
FROM
(SELECT
c.cuid,
c.name AS name,
c.address AS address,
b.month AS Month,
0 AS Received,
b.bill_amount AS Amount
FROM
customer c
INNER JOIN billing b ON c.cuid=b.cuid
UNION ALL
SELECT
c.cuid,
c.name AS Name,
c.address AS Address,
null AS Month,
t.received_amount AS Received,
0 AS Amount
FROM
customer c
INNER JOIN transaction t ON c.cuid = t.cuid) AS due
GROUP BY
due.cuid;
Code generated table is :
cuid
Name
Address
Month
Due_Amount
1
David
City 1
1
150
2
Roja
City 2
1
0
You probably don't need all that SUM(), UNION ALL and subquery. You can do it in a single query and JOIN all three tables like this:
SELECT c.cuid,
c.Name,
c.Address,
b.Month,
t.received_amount-b.bill_amount AS Due_Amount
FROM customer c
JOIN billing b
ON c.cuid=b.cuid
JOIN transaction t
ON c.cuid=t.cuid
AND b.month=MONTH(t.date);
Demo fiddle
I do have a slight curiosity though because my understanding of Due_amount is the remaining amount need to be paid by the customer and yours doesn't seem to be one. If it is, then the value should be negative because the customer David paid more (received_amount) than the bill_amount.
I have multiple tables and I need to aggregate the data from all of them, but it seems that I always get the wrong results for the sums. What am I doing wrong?
customers
ID Name
1 c1
2 c2
3 c3
budget
ID Cust_ID Value
1 1 100
2 1 300
3 2 600
4 3 450
forecast
ID Cust_ID Value
1 1 200
2 1 500
3 2 100
4 2 700
5 3 550
orders
ID Cust_ID Net_Sales
1 1 100
2 1 200
3 1 300
4 2 400
5 3 500
Here is the expected result:
ID Name sum(budget.Value) sum(forecast.Value) sum(orders.Net_Sales) count(orders.ID)
1 c1 400 700 600 3
2 c2 600 800 400 1
3 c3 450 550 500 1
And here's what I've tried so far:
SELECT customers.ID, customers.Name, sum(budget.Value), sum(forecast.Value), sum(orders.Net_Sales), count(orders.ID)
FROM customers
INNER JOIN budget ON budget.Cust_ID = customers.ID
INNER JOIN forecast ON forecast.Cust_ID = customers.ID
INNER JOIN orders ON orders.Cust_ID = customers.ID
GROUP BY customers.ID
ORDER BY customers.ID ASC
You are joining along multiple dimensions, which multiplies the results.
A simple solution is correlated subqueries:
SELECT c.ID, c.Name,
(SELECT SUM(b.Value)
FROM budget b
WHERE b.Cust_ID = c.ID
) as budget,
(SELECT SUM(f.Value)
FROM forecast f
WHERE f.Cust_ID = c.ID
) as forecast,
(SELECT SUM(o.Net_Sales)
FROM orders o
WHERE o.Cust_ID = c.ID
) as net_sales
FROM customers c
ORDER BY c.ID ASC;
With the right indexes in the second tables (budget(cust_id, value), and so on), this may actually be faster than a JOIN approach.
I have two tables, allowances & salaries,
Allowances table looks like,
Id Title value
1 Transport 2000
2 Housing 1000
3 Housing 1000
The Salaries table,
id Salary
1 2000
2 1000
3 3000
For id's with no Housing allowance the value should be considered as 0 for housing and just the salary should be shown. If housing allowance is available, add up salary and housing.
My query is not exactly giving the right output,
SELECT
s.id,
CASE
WHEN t.`Housing` = 0 THEN s.salary
END AS Salary,
CASE
WHEN t.`Housing` <> 0 THEN t.Housing + s.salary
WHEN t.`Housing` = 0 THEN s.salary
END AS SalaryAndHousing
FROM
(SELECT
id,
CASE
WHEN Title = 'Housing' THEN value
WHEN Title <> 'Housing' THEN 0
END AS 'Housing'
FROM
Allowance) t
JOIN
Salaries s ON (t.id = s.id);
The output of my query is,
id Salary SalaryAndHousing
1 2000 2000
2 null 2000
3 null 4000
It should look like,
id Salary SalaryAndHousing
1 2000 2000 -- 2000 + 0
2 1000 2000 -- 1000 + 1000
3 3000 4000 -- 1000 + 3000
dbfiddle
This is can be pretty simple query:
select
s.id,
s.Salary,
s.Salary + coalesce(a.value, 0) SalaryAndHousing
from Salaries s
left join Allowance a on a.id = s.id and a.Title = 'Housing'
order by s.id;
Try it on SQLize.online
I have 3 tables: product, customer and transaction.
Product:
id_product price
1 1000
2 2000
Customer:
id_customer name
1 Tom
2 Jack
Transaction:
id_transaction id_product id_customer qty date
1 1 1 10 2013-02-21
2 2 1 50 2013-02-21
3 1 2 15 2013-02-21
I want to achieve this result:
id_customer name total_transaction purchase_qty subtotal
1 Tom 2 60 110000
2 Jack 1 15 15000
How I can get that result using a query in MySQL?
SELECT t.id_customer, c.name,
COUNT(t.id_customer) AS total_transaction,
SUM(t.qty) as purchase_qty
FROM transaction t
INNER JOIN customer c
ON t.id_customer = c.id_customer
GROUP BY t.id_customer,c.name
SELECT cs.id_customer, cs.name, COUNT(tr.transaction) AS total_transaction, SUM(tr.qty) as purchase_qty, SUM(tr.qty*pr.prize)
FROM customer AS cs
LEFT JOIN transaction AS tr ON tr.id_customer = cs.id_customer
LEFT JOIN product AS pr ON pr.id_product = tr.id_product
GROUP BY cs.id_customer
I suppose you are a total beginner, so I did this for you. Next time, if you have ANY own ideas, give to us, so we don't have to write the whole query for you. Show some effort.
SELECT c.id_customer, c.name, count(t.id_transaction) AS total_transaction
FORM Customer c INNER JOIN Transaction T
ON C.id_customer = T.id_customer
GROUP BY c.id_customer
You need a group by statement since you want to aggregate results for a given customer :
SELECT id_customer, name, count(id_transaction) AS total_transaction
FORM Customer, Transaction
WHERE Transaction.id_customer = Customer.id_customer
GROUP BY id_customer
This does not solve your whole problem, but you've got the idea.