MySQL - different description in table with ids from the same table - mysql

i have these tables:
tb_employee:
ID EMPLOYEE
1 Jhonatan Sandoval
2 Patricia Sanchez
3 Ken Dawson
tb_bankacc:
ID BANK AMOUNT OWNER (from tb_employee)
1 Bank 1 250000 1
tb_pay:
ID OWNER EMPLOYEE AMOUNT
1 1 2 500
2 1 3 480
I need to make a SELECT QUERY to show the names of employees, like this:
ID OWNER EMPLOYEE AMOUNT
1 Jhonatan Sandoval Patricia Sanchez 500
2 Jhonatan Sandoval Ken Dawson 480
But, i don't know how.

Use
SELECT p.Id, o.Employee AS Owner, e.Employee, p.Amount
FROM tb_pay p
INNER JOIN tb_employee e ON e.Id = p.Employee
INNER JOIN tb_employee o ON o.Id = p.Owner
You're joining to the tb_employee table twice, once to get the names for the Employee column (by joining the Id in the Employee column with the Id in tb_employee - and then taking the name from that record) and then again to get the names for the Owner column (joining the Id in the Owner column to the Id in tb_employee).

Related

How to count how many having how many in mysql

I have persons i one table [person] and cars [car] registered to each person i another, connected by id.
I want to get a list of how many persons having how many cars.
Something like this:
PERSON
id
name
1
LISA
2
ADAM
3
RAY
CARS
id
id_person
brand
1
3
FORD
2
1
BMW
3
2
VOLVO
4
1
VOLVO
5
1
VW
RESULT
no cars
no persons
1
2
2
0
3
1
Just dont get how to do it?
You need to do it in two stages. The first is to get the number of cars per person -
SELECT p.id, COUNT(*) num_cars
FROM person p
JOIN cars c ON p.id = c.id_person
GROUP BY p.id
This can then be nested to count people per count -
SELECT num_cars, COUNT(*) num_people
FROM (
SELECT p.id, COUNT(*) num_cars
FROM person p
JOIN cars c ON p.id = c.id_person
GROUP BY p.id
) t
GROUP BY num_cars
ORDER BY num_cars ASC

MYSQL : Get data from multiple table using JOIN and UNION in single row

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.

How to select a row from table1 if the row id isn't present in table2 more than x times

accounts as a1 | team_logs as tl1
--------------------------------------------------------
id Name counter | id team_id user_id account_id
1 Account 1 2 | 1 1 100 1
2 Account 2 2 | 2 2 200 1
3 Account 3 0 | 3 3 300 2
... | 4 2 200 2
This is an account review app. Based on the 2 tables above a query is needed that will output 1 account from a1 table based on the tl1 records as below:
A team member is requesting an account, and once an account is assigned to him a log entry is made in tl1 that an account_id is assigned to him.
An account can be assigned to a Team only once.
An account can be assigned to x teams (In the above example we have only 3 teams).
An record can be reviewed x times(In the example above it can be reviewed 3 times).
I had a project where I had only 3 teams and each teams logs were stored in its own table, and I had this query which worked:
Example for Team1
SELECT `a1`.*
FROM `accounts` AS `a1`
LEFT JOIN `team1_logs` AS `tl1` ON tl1.account_id = a1.id
WHERE (tl1.account_id IS NULL)
AND (a1.counter < '3')
ORDER BY RAND()
LIMIT 1
a1 has a counter column which has a value that represents the number of times a row was shown to teams. Now my project can house x teams, we made the teams dynamic, so making a table log for each team isn't an option.
So in the above tables if i want an account to be reviewed(assigned to a team member) 3 times.
Account 1 can be reviewed 1 more time by any team that isn't 1 and 2
Account 2 can be reviewed 1 more time by any team that isn't 2 and 3
What would my new query need to look like if i want to get the next first available record, based on the 1-4 criteria from above?
The data in Table 2 is more than enough, you don't need to know any other
data to make the needed query.
team_id is an query input (since we need to output an account to the team
member)
Answer
Assuming that I am a team member of team 1
SELECT DISTINCT a.*
FROM accounts AS a
LEFT JOIN (
SELECT account_id, team_id FROM team_logs) AS tl1 ON a.id = tl1.account_id
WHERE a.id NOT IN (
SELECT account_id FROM team_logs WHERE team_id =1)
AND a.counter < 3
ORDER BY a.id ASC
If you just want to see which teams are not allowed to review the account again, join with a subquery that uses GROUP_CONCAT to get the list of teams that have reviewed it.
SELECT a.*, 3 - counter AS remaining_reviews, IFNULL(tl.already_reviewed, '') AS already_reviewed
FROM accounts AS a
LEFT JOIN (
SELECT account_id, GROUP_CONCAT(team_id ORDER BY team_id) AS already_reviewed
FROM team_logs
GROUP BY account_id) AS tl ON a.id = tl.account_id
WHERE a.counter < 3
DEMO

How to join 3 table with this condition?

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.

MySQL Join Multiple (More than 2) Tables with Conditions

Assume I have 4 tables:
Table 1: Task
ID Task Schedule
1 Cut Grass Mon
2 Sweep Floor Fri
3 Wash Dishes Fri
Table 2: Assigned
ID TaskID (FK) PersonID (FK)
1 1 1
2 1 2
3 2 3
4 3 2
Table 3: Person
ID Name
1 Tom
2 Dick
3 Harry
Table 4: Mobile
ID PersonID (FK) CountryCode MobileNumber
1 1 1 555-555-5555
2 2 44 555-555-1234
3 3 81 555-555-5678
4 3 81 555-555-0000
I'm trying to display the
Task on a certain day
Name of person assigned to task
Phone numbers of said person
I think it should be something like the following, but I'm not sure how to set up the conditions so that the results are limited correctly:
SELECT T.ID, T.Task, P.Name, M.MobileNumber
FROM Task AS T
LEFT JOIN Assigned AS A
ON T.ID = A.TaskID
LEFT JOIN Person AS P
ON A.PersonID = P.ID
LEFT JOIN Mobile AS M
ON M.PersonID = P.ID
WHERE T.Schedule = Fri
My goal is to fetch the following information (it will be displayed differently):
Tasks Name MobileNumber
Sweep Floor, Wash Dishes Dick, Harry 44-555-555-1234, 81-555-555-5678, 81-555-555-0000
Of course, if JOIN is the wrong way to do this, please say so.
It's unclear what you want to do with duplicate data in this case, but you should be looking at using inner joins instead of outer joins, and using something like group_concat() to combine the phone numbers.