How to use SQL SELECT as field name - sql

I'm trying to use select as column name to store the get total member, But I didn't succeed to get the solution for the right sql statement to use.
Here is my database table structure and sql that I have used.
Sql
SELECT
name,
SELECT
(
(COALESCE(SUM(adult),0) + COALESCE(SUM(elders),0))
) as total
FROM members
LEFT JOIN company
ON company.companyId = members.companyId
GROUP BY company.companyId
My tables
company table
+----------------------+
| companyId | Name |
+-----------+----------+
| 1 | Company1 |
| 2 | Company2 |
+-----------+----------+
members table
+--------------------------------------------+
| id | companyId | gender | adult | elders |
+------+-----------+--------+-------+--------+
| 1 | 1 | male | 200 | 700 |
| 1 | 1 | female | 300 | 50 |
| 1 | 2 | male | 100 | 500 |
| 1 | 2 | female | 900 | 800 |
+------+-----------+--------+-------+--------+
expected Results table
+-------------------------------------------------+
| companyId | Name | adult | elders | Total |
+-----------+----------+-------+--------+---------+
| 1 | Company1 | 500 | 750 | 1250 |
| 1 | Company2 | 1000 | 1300 | 2300 |
+-----------+----------+-------+--------+---------+
Thanks in advance

A LEFT JOIN starting on members is not appropriate, unless members could lack a company. I'll just use a regular JOIN.
Then you want aggregation with arithmetic:
SELECT c.companyId, c.name,
SUM(m.adults + m.elders) as total,
SUM(m.adults) as adults, SUM(m.elders) as elders
FROM members m JOIN
company c
ON c.companyId = m.companyId
GROUP BY c.companyId, c.name;
You would use a LEFT JOIN if one of the following were true and you wanted to avoid filtering rows out:
Some members do not have a valid companyId.
Some companies have no rows in members.

Related

how to sum a column of a queried table in sql

I have this table from a query and I would like to find the sum of the Total Cost (after discount). I have searched for a solution but I can't seem to find the one I'm looking for.
Here are the sample data from my tables
Booking
+-----------+-------------+----------+------------+
| vehicleNo |  bookingDay | driverNo | acc_status |
+-----------+-------------+----------+------------+
| 10 | 13/06/2021 | 2 | B |
| 10 | 14/06/2021 | 0 | B |
| 10 | 15/06/2021 | 2 | B |
| 20 | 17/06/2021 | 2 | B |
+-----------+-------------+----------+------------+
Vehicle
+-----------+-------------+----------------+------+
| vehicleNo |  vehicleReg | make_model | cost |
+-----------+-------------+----------------+------+
| 10 | IN10NGT | Nissan R34 GTR | 90 |
| 20 | IN10MRX | Mazda RX7 | 70 |
| 30 | IN10TSU | Toyota Supra | 80 |
+-----------+-------------+----------------+------+
Here is the query
SELECT IF(COUNT(Vehicle.vehicleNo) > 1, ROUND(Vehicle.cost,1) * ROUND(COUNT(Vehicle.vehicleNo) * 0.9,1), Vehicle.cost * ROUND(COUNT(Vehicle.vehicleNo),1)) AS 'Total after discount'
FROM Booking
INNER JOIN Vehicle
ON Vehicle.vehicleNo = Booking.vehicleNo
WHERE Booking.driverNo = 2
GROUP BY Vehicle.vehicleNo
ORDER BY Vehicle.vehicleNo;
an here is the result
+----------------------+
| Total after discount |
+----------------------+
| 162 |
| 70 |
+----------------------+
and I am expecting to have a table after calculating the sum like this
+----------------------+
| Overall cost |
|after discount |
+----------------------+
| 232 |
+----------------------+
any help is much appreciated.
i have figured it out. i used this query:
SELECT SUM(Cost) FROM (SELECT IF(COUNT(Vehicle.vehicleNo) > 1, ROUND(Vehicle.cost,1) * ROUND(COUNT(Vehicle.vehicleNo) * 0.9,1), Vehicle.cost * ROUND(COUNT(Vehicle.vehicleNo),1)) AS Cost
FROM Vehicle INNER JOIN Booking
ON Vehicle.vehicleNo = Booking.vehicleNo AND Booking.driverNo = 2
GROUP BY Vehicle.vehicleNo) AS x;

How to select data from database with two tables

I have two tables named at Exams, Payments.
In this Exams table I stored all exam details on my college
| id | examid | fees |
----------------------
| 1 | exam01 | 1000 |
| 2 | exam02 | 3000 |
| 3 | exam03 | 2500 |
In this Payments table i stored all payments details from my students
| id | examid | uname | fees |
------------------------------
| 1 | exam01 | kumar | 1000 |
| 2 | exam02 | kumar | 3000 |
| 3 | exam01 | johny | 1000 |
| 4 | exam03 | johny | 2500 |
Now i need to select all non-payable exams from kumar user Like this
| id | examid | fees |
----------------------
| 3 | exam03 | 2500 |
I tried Joins, Unions queries but I dont know how to use this.
is this any solution for my issue
Try this:
SELECT
e.Id,
e.ExamId,
e.Fees
FROM
Exams AS e
LEFT JOIN Payments AS p ON p.ExamId = e.ExamId
AND p.uname = 'kumar'
WHERE
p.Id IS NULL
you can use following query
select *
from Exams
where id not in
(select Exams.id
from
(select * from Payments where uname = 'kumar') t join Exams on t.examid = Exams.examid)

How to SUM rows with an outer join?

Question:
I have the following tables that I'd like to sum on two fields: HOURS and RATE. I also want to retrieve the NAME from the third table, joining all 3 tables on the field LINE_NUM.
If the LINE_NUM and CODE are the same, sum the fields of A with B.
Table EARNINGS A:
| EMPLOYEE_ID | LINE_NUM | REG_CODE | REG_HOURS | REG_RATE |
------------------------------------------------------------
| 0001 | 1 | C | 20 | 200 |
| 0002 | 1 | H | 0 | 0 |
Table OTH_EARNINGS B:
| LINE_NUM | OTH_CODE | OTH_HOURS | OTH_RATE |
----------------------------------------------
| 1 | A | 0 | 0 |
| 1 | B | 0 | 0 |
| 1 | C | 10 | 100 |
| 2 | A | 50 | 50 |
Table PAYCHECK C:
| EMPLOYEE_ID | LINE_NUM | NAME |
---------------------------------
| 0001 | 1 | Tom |
| 0001 | 2 | Tom |
| 0002 | 1 | John |
The result I'm looking for should be:
| EMPLOYEE_ID | LINE_NUM | CODE | HOURS | RATE | NAME |
-------------------------------------------------------
| 0001 | 1 | A | 0 | 0 | Tom |
| 0001 | 1 | B | 0 | 0 | Tom |
| 0001 | 1 | C | 30 | 300 | Tom |
| 0001 | 2 | A | 50 | 50 | Tom |
| 0002 | 1 | H | 0 | 0 | John |
Any idea how I can achieve this?
What I tried:
I've tried (table A with C) UNION (table B with C), but I can't get the sums to work.
SELECT C.EMPLOYEE_ID, A.REG_CODE, A.REG_HRS, SUM(A.REG_RATE)
FROM EARNINGS A, PAYCHECK C
WHERE A.LINE_NUM = C.LINE_NUM
GROUP BY C.EMPLOYEE_ID, A.REG_CODE, A.REG_HRS
UNION
SELECT D.EMPLOYEE_ID, B.OTH_CODE, B.OTH_HRS, SUM(B.OTH_RATE)
FROM OTH_EARNINGS B, PAYCHECK D
WHERE B.LINE_NUM = D.LINE_NUM
GROUP BY D.EMPLOYEE_ID, B.OTH_CODE, B.OTH_HRS
But I couldn't get the sum to work and it returned:
| EMPLOYEE_ID | LINE_NUM | CODE | HOURS | RATE | NAME |
-------------------------------------------------------
| 0001 | 1 | A | 0 | 0 | Tom |
| 0001 | 1 | B | 0 | 0 | Tom |
| 0001 | 1 | C | 10 | 100 | Tom |
| 0001 | 1 | C | 20 | 200 | Tom |
| 0001 | 2 | A | 50 | 50 | Tom |
| 0002 | 1 | H | 0 | 0 | John |
Your approach wasn't bad and you were almost there.
You should make the GROUP BY on the results of the 2 UNIONed queries being nested:
SELECT EMPLOYEE_ID, NAME, CODE, SUM(HRS), SUM(RATE)
FROM
(
SELECT C.EMPLOYEE_ID, C.NAME, A.REG_CODE AS CODE, A.REG_HRS AS HRS, A.REG_RATE AS RATE
FROM EARNINGS A
INNER JOIN PAYCHECK C ON A.LINE_NUM = C.LINE_NUM
UNION ALL
SELECT D.EMPLOYEE_ID, C.NAME, B.OTH_CODE AS CODE, B.OTH_HRS AS HRS, B.OTH_RATE AS RATE
FROM OTH_EARNINGS B
INNER JOIN PAYCHECK D ON B.LINE_NUM = D.LINE_NUM
)
GROUP BY EMPLOYEE_ID, NAME, CODE
However this will return wrong results because the JOINs on the PAYCHECK table will returns duplicates.
There's obviously something missing somewhere.
To identify the employee, you should combine 2 columns : EMPLOYEE_ID and LINE_NUM. For the first query on EARNING, there's no issue as the EMPLOYEE_ID is present in the table. However for the second query on OTH_EARNINGS, the EMPLOYEE_ID is missing...
In theory you should have something like this (check the INNER JOIN...ON)
SELECT EMPLOYEE_ID, NAME, CODE, SUM(HRS), SUM(RATE)
FROM
(
SELECT C.EMPLOYEE_ID, C.NAME, A.REG_CODE AS CODE, A.REG_HRS AS HRS, A.REG_RATE AS RATE
FROM EARNINGS A
INNER JOIN PAYCHECK C ON A.LINE_NUM = C.LINE_NUM AND A.EMPLOYEE_ID = C.EMPLOYEE_ID
UNION ALL
SELECT D.EMPLOYEE_ID, C.NAME, B.OTH_CODE AS CODE, B.OTH_HRS AS HRS, B.OTH_RATE AS RATE
FROM OTH_EARNINGS B
INNER JOIN PAYCHECK D ON B.LINE_NUM = D.LINE_NUM AND B.EMPLOYEE_ID = D.EMPLOYEE_ID
)
GROUP BY EMPLOYEE_ID, NAME, CODE
I also changed from your initial query:
the JOINs from implicit to explicit syntax.
the UNION into an UNION ALL as there's no reason here to remove the duplicates (maybe I am wrong)

postgresql aggregate of aggregate (sum of sum)

I've got workers who have many sales and who belong to departments. I'd like to see how many sales a department is making per day.
For simplicity, let's say a worker belongs to only one department.
Example:
departments:
| id | name |
| 1 | Men's Fashion |
| 2 | Women's Fashion |
workers:
| id | name |
| 1 | Timmy |
| 2 | Sally |
| 3 | Johnny |
sales:
| id | worker_id | datetime | amount |
| 1 | 1 | 2013-1-1 08:00:00 | 1 |
| 2 | 1 | 2013-1-1 09:00:00 | 3 |
| 3 | 3 | 2013-1-2 08:00:00 | 8 |
department_employees
| id | worker_id | department_id |
| 1 | 1 | 1 |
| 2 | 2 | 1 |
| 3 | 3 | 2 |
I'd like to get
| department | amount |
| Men's Fashion | 4 |
| Women's Fashion | 8 |
To get the individual worker's total sales, I can do
SELECT worker_id, SUM(amount) FROM sales
GROUP BY worker_id
How do I take those sums (the total amount sold per worker) and aggregate it by department?
Don't sum the sum, rather join from sales through the department_employees table to the department:
select d.name, sum(s.amount)
from sales s
join department_employees de on de.worker_id = s.worker_id
join departments d on d.id = de.department_id
group by d.name
Aggregate functions and group by work in a statement with joints too.
Try something like:
SELECT name, SUM(amount) FROM departments, department_employees, sales
WHERE departments.id = department_employees.department_id
AND sales.worker_id = department_employees.worker_id
GROUP BY name

How to return smallest value inside the resultset as a separate column in SQL?

I've been struggling with the following SQL query.
My resultset is now:
| Id | Customer | Sales |
| 1 | 1 | 10 |
| 2 | 1 | 20 |
| 3 | 2 | 30 |
| 4 | 2 | 40 |
What I'd like to do is to add additional column that shows the smallest sale for that customer:
| Id | Customer | Sales | SmallestSale |
| 1 | 1 | 10 | 10 |
| 2 | 1 | 20 | 10 |
| 3 | 2 | 30 | 30 |
| 4 | 2 | 40 | 30 |
As the select query to get those three columns is now rather complex I'd like to avoid subqueries.
Any ideas?
Mika
Assuming your RDBMS supports windowed aggregates
SELECT Id,
Customer,
Sales,
MIN(Sales) OVER (PARTITION BY Customer) AS SmallestSale
FROM YourTable
select s.Id, s.Customer, s.Sales, sm.SmallestSale
from Sales s
inner join (
select Customer, min(sales) as SmallestSale
from Sales
group by Customer
) sm on s.Customer = sm.Customer