How to select data from database with two tables - sql

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)

Related

How to use SQL SELECT as field name

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.

How to get following data via SQL

I was struggling on how to get the following data.
I have 2 tables:
| Company Name | Customer ID 1 | Customer ID 2 | Customer ID 3
+----------------+---------------+---------------+-----------------
| Android | 1 | 2 | 3
| IOS | 4 | 5 | 6
And the following table
| Customer ID | Customer Name |
+--------------+---------------+
| 1 | Edwin |
| 2 | Stanley |
| 3 | Roward |
| 4 | Kim |
| 5 | Flare |
| 6 | Queen |
How can I get the result such as this in SQL query?
| Company Name | Customer Name1 | Customer Name2 | Customer Name3
+----------------+----------------+----------------+---------------
| Android | Edwin | Stanley | Roward
| IOS | Kim | Flare | Queen
You can join, join ... and join:
select
t.company_name,
c1.customer_name customer_name1,
c2.customer_name customer_name2,
c3.customer_name customer_name3
from mytable t
inner join customers c1 on c1.customer_id = t.customer_id1
inner join customers c2 on c2.customer_id = t.customer_id2
inner join customers c3 on c3.customer_id = t.customer_id3
An important thing here is to use different table aliases for each join to avoid conflicts on the table that is joined multiple times.

SQL join where only the max value should be returned

Looking for some help with SQL. I have the following 4 tables
Users Table
+-----------------------------+
| ID | First_Name | Last_Name |
+-----------------------------+
| 1 | Billy | O'Neal |
+----+------------+-----------+
| 2 | John | Skeet |
+----+------------+-----------+
| 3 | Ken | Stamp |
+----+------------+-----------+
| 4 | Doug | Feng |
+----+------------+-----------+
Book_CheckOut
+----+--------------+---------------+
| ID | User_ID | Book_ID |
+-----------------------------------+
| 1 | 1 | 1 |
+----+--------------+---------------+
| 2 | 2 | 3 |
+----+--------------+---------------+
| 3 | 2 | 1 |
+----+--------------+---------------+
| 4 | 2 | 2 |
+----+--------------+---------------+
| 5 | 3 | 1 |
+----+--------------+---------------+
| 6 | 1 | 4 |
+----+--------------+---------------+
| 7 | 1 | 0 |
+----+--------------+---------------+
Books
+---------+-------------+-------------+
| ID | Book_Name | Location_ID |
+-----------------------+-------------+
| 1 | Programming | 1 |
+---------+-------------+-------------+
| 2 | Cooking | 3 |
+---------+-------------+-------------+
| 3 | Dancing | 2 |
+---------+-------------+-------------+
| 4 | Sports | 1 |
+---------+-------------+-------------+
Location
+---------+-------------+
| ID | Loc_Name |
+-----------------------+
| 1 | Palo Alto |
+---------+-------------+
| 2 | San Jose |
+---------+-------------+
| 3 | Oakland |
+---------+-------------+
| 4 | Cupertino |
+---------+-------------+
What I am trying to get to is to figure out all the person with the latest book checked out. If the person doesn't have any record, he should show up. If there are no book matched such as 0 which means that the person returned all book. He should show up as well.
End results
Record
+-----------------+----------------+----------------+
| First_Name | Book_Name | Loc_Name |
+-----------------+----------------+----------------+
| Billy | | |
+-----------------+----------------+----------------+
| John | Cooking | Oakland |
+-----------------+----------------+----------------+
| Ken | Programming | Palo Alto |
+-----------------+----------------+----------------+
| Doug | | |
+-----------------+----------------+----------------+
Billy doesn't have anything since his last record in Book_CheckOut is 0 and Doug doesn't have anything since there are no record of him in Book_CheckOut.
I have tried various join with MAX() and group by but there doesn't seem to be a way to satisfy all of what I am looking for.
Any help is greatly appreciated.
try this:
select
u.first_name,
b.book_name,
l.loc_name
from user u
left join (select *
from book_checkout t0
where id = (select
max(id)
from book_checkout
where user_id = t0.user_id
)
) bc on bc.user_id = u.id
left join books b on b.id = bc.book_id
left join location l on l.id = b.location_id
subquery inside first join statement is used to select only last records for every user. But this query is considered that every user checkout only 1 book at a time.
Let me know if it works )
SELECT LC.First_Name
, ISNULL(B.Book_Name, N'') AS BookName
, ISNULL(L.Loc_Name, N'') AS Loc_Name
FROM Books AS B
INNER JOIN Book_CheckOut AS BC ON B.ID = BC.Book_ID
INNER JOIN Location AS L ON B.ID = L.ID
RIGHT OUTER JOIN (SELECT U.First_Name
, ISNULL(MAX(BC.ID), 0) AS BCID
FROM Users AS U
LEFT OUTER JOIN Book_CheckOut AS BC ON U.ID = BC.User_ID
GROUP BY U.First_Name) AS LC ON BC.ID = LC.BCID
The subquery shows Last CheckOut of all users.
select First_Name, Book_Name, Location_Name
from Users U, (select * from Books_Checkout where ID in (select max(ID) from Books_Checkout group by User_ID) and Book_ID is not null order by ID) BC, Books B, Location L
where U.ID = BC.User_ID and B.ID = BC.Book_ID and L.ID = B.Location_ID;
The above query results:
John Cooking Oakland
Ken Programming Palo Alto

Select all child record but need values of parent or grandparent record

I'm working on a project that uses a MariaDB v5.5 database to keep track of employees in a tree based higherarchy. Each person in this tree can have various 'flags' associated with them. In this case, these flags are stored using a bitmask.
My objects look like the following
Employee Table description
+--------------+-------------+--------------------------------------+
| Name | Field | Description |
+--------------+-------------+--------------------------------------+
| employee_id | INT | Unique key |
| name | VARCHAR(45) | Employees name |
| flags | INT(4) | Bitmask of employee attributes |
| parent_id | INT | the employee_id of the parent record |
+--------------+-------------+--------------------------------------+
'flag' bitmap description
+-----+--------------+
| Bit | Flag |
+-----+--------------+
| 0 | CEO |
| 1 | MANAGER |
| 2 | PROJECT_LEAD |
| 3 | SALES_PERSON |
| 4 | MAINTANCE |
+-----+--------------+
Employee Table Data
+----+--------+------------+---------------------------+
| id | name | parent_id | flags |
+----+--------+------------+---------------------------+
| 1 | Lisa | NULL | CEO |
| 2 | Steve | 1 | MANAGER |
| 3 | Pat | 1 | MANAGER |
| 4 | Mary | 2 | SALES_PERSON,PROJECT_LEAD |
| 5 | Phil | 4 | SALES_PERSON,MAINTANCE |
| 6 | Jim | 3 | SALES_PERSON,MAINTANCE |
| 7 | Anna | 3 | SALES_PERSON,MAINTANCE |
+----+--------+------------+---------------------------+
Let's say I want to query all employees who have the "MAINTANCE" flag BUT, I need to return the id of the parent record that has the "MANAGER" flag. So my result should look like this.
> SELECT id, name, manager_id, manager_name FROM ...
+----+--------+------------+--------------+
| ID | Name | manager_id | manager_name |
+----+--------+------------+--------------+
| 5 | Phil | 2 | Steve |
| 6 | Jim | 3 | Pat |
| 7 | Anna | 3 | Pat |
+----+--------+------------+--------------+
So how do I build my query to give me what I want?
Note, that this tree can be more than just 3 levels deep and the query still needs to work.
Select
a.ID
,a.Name
,a.manager_ID
,b.Manager_Name
From
EmployeeTable As a
Left Join
EmployeeTable As b
On
a.Mangager_ID = b.ID
Where
a.Flag = 'Maintenance'
And
b.Flag = 'Manager'
This should give you what you are looking for.

Generate report using SUM

I've got two SQL Server 2005 tables: MainTable and Orders.
MainTable:
| MainID | Serial |
-------------------
| 1 | A00001 |
| 2 | B00002 |
Orders:
| OrderID | MainID | Name | Value |
-----------------------------------
| 1 | 2 | John | 100 |
| 2 | 2 | Mike | 200 |
| 3 | 1 | John | 150 |
| 4 | 1 | Mike | 350 |
| 5 | 1 | John | 200 |
| 6 | 2 | John | 500 |
| 7 | 1 | Mike | 50 |
I want to get something like this:
|Serial | Name | Total |
-----------------------
| A00001 | John | 350 |
| A00002 | John | 600 |
| A00001 | Mike | 400 |
| A00002 | Mike | 200 |
SELECT
m.serial,
o.name,
SUM(o.value)
FROM
main m
INNER JOIN order o ON m.mainid = o.mainid
GROUP BY
o.name,
m.serial
select serial, name, sum(value) as total
from maintable m inner join orders o on
m.mainID = o.mainID
group by
serial, name
SELECT
M.SERIAL, O.NAME, SUM(VALUE) AS TOTAL
FROM MAINTABLE M JOIN ORDERS O ON O.MAINID=M.MAINID
GROUP BY M.SERIAL, O.NAME
select Serial , name , Total
from MainTable m,
( select MainID ,name, SUM(value) Total from Orders o group by MainID , Name ) O
where m.MainID= O.MainID