How to get following data via SQL - 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.

Related

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)

Sum with 3 tables to join

I have 3 tables. The link between the first and the second table is REQ_ID and the link between the second and the third table is ENC_ID. There is no direct link between the first and the third table.
INS_RCPT
+----+--------+------+----------+
| ID | REQ_ID | CURR | RCPT_AMT |
+----+--------+------+----------+
| 1 | 1 | USD | 100 |
| 2 | 2 | USD | 200 |
| 3 | 3 | USD | 300 |
+----+--------+------+----------+
ENC_LOG
+----+--------+--------+-------------+
| ID | REQ_ID | ENC_ID | ENC_LOG_AMT |
+----+--------+--------+-------------+
| 1 | 1 | 1 | 20 |
| 2 | 1 | 2 | 50 |
| 3 | 1 | 3 | 30 |
| 4 | 2 | 4 | 20 |
+----+--------+--------+-------------+
ENC_RCPT
+----+--------+--------------+
| ID | ENC_ID | ENC_RCPT_AMT |
+----+--------+--------------+
| 1 | 1 | 10 |
| 2 | 1 | 10 |
| 3 | 2 | 15 |
| 4 | 2 | 25 |
| 5 | 2 | 10 |
| 6 | 3 | 12 |
| 7 | 3 | 18 |
| 8 | 4 | 10 |
+----+--------+--------------+
I would like to have output as follows:
+----+--------+------+----------+-------------+--------------+
| ID | REQ_ID | CURR | RCPT_AMT | ENC_LOG_AMT | ENC_RCPT_AMT |
+----+--------+------+----------+-------------+--------------+
| 1 | 1 | USD | 100 | 100 | 100 |
| 2 | 2 | USD | 200 | 20 | 10 |
| 3 | 3 | USD | 300 | 0 | 0 |
+----+--------+------+----------+-------------+--------------+
I am using SQL Server to write this query. Any help is appreciated.
One approach would be to join the first table to two subqueries which compute the sums separately:
SELECT
ir.ID,
ir.REQ_ID,
ir.CURR,
ir.RCPT_AMT,
el.ENC_LOG_AMT,
er.ENC_RCPT_AMT
FROM INS_RCPT ir
LEFT JOIN
(
SELECT REQ_ID, SUM(ENC_LOG_AMT) AS ENC_LOG_AMT
FROM ENC_LOG
GROUP BY REQ_ID
) el
ON ir.REQ_ID = el.REQ_ID
LEFT JOIN
(
SELECT t1.REQ_ID, SUM(t2.ENC_RCPT_AMT) AS ENC_RCPT_AMT
FROM ENC_LOG t1
INNER JOIN ENC_RCPT t2 ON t1.ENC_ID = t2.ENC_ID
GROUP BY t1.REQ_ID
) er
ON ir.REQ_ID = er.REQ_ID
Demo
Note that your question includes a curve ball. The second subquery needs to return aggregates of the receipt table by REQ_ID, even though this field does not appear in that table. As a result, we actually need to join ENC_LOG to ENC_RCPT in that subquery, and then aggregate by REQ_ID.
You can try the below query. Also change the join from left to inner as per your requirement.
select a.id,a.req_id,a.curr,sum(a.rcpt_amt) rcpt_amt,sum(a.enc_log_amt) enc_log_amt,sum(c.enc_rcpt_amt) enc_rcpt_amt
from
(
select a.id id ,a.req_id req_id ,a.curr curr,sum(rcpt_amt) as rcpt_amt,sum(enc_log_amt) as enc_log_amt
from ins_rcpt a
left join enc_log b
on a.req_id=b.req_id
group by id,req_id,curr
) a
left join enc_rcpt c
on a.enc_id = c.enc_id
group by id,req_id,curr;

SQL column values based on values from another table

I'm new to SQL and can't figure this simple thing out.
I have two tables:
+----------+----------+
| Person_1 | Person_2 |
+----------+----------+
| 1 | 2 |
| 1 | 4 |
| 3 | 2 |
+----------+----------+
and
+----+------+
| ID | City |
+----+------+
| 1 | A |
| 2 | B |
| 3 | A |
| 4 | A |
+----+------+
The values in columns Person_A and Person_B refer to the ID in the second table. I want to combine these two tables to have a resulting table like this:
+----------+----------+---------------+---------------+
| Person_1 | Person_2 | Person_1_City | Person_2_City |
+----------+----------+---------------+---------------+
| 1 | 2 | A | B |
| 1 | 4 | A | A |
| 3 | 2 | A | B |
+----------+----------+---------------+---------------+
How can I do this?
Use JOIN with city twice:
select p.persion1, p.persion2,
c1.city as persion1city,
c2.city as persion2city
from person p
left join city c1 on p.Person_1 = c1.id
left join city c2 on p.Person_2 = c2.id

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

Finding number of types of accounts from each customer

I am having a lot of trouble with trying to construct a query that will give me the name of each customer and the number of different types of accounts each has. The three types are Checkings, Savings, and CD.
customers:
+--------+--------+
| cid | name |
+--------+--------+
| 1 | a |
| 2 | b |
| 3 | c |
+--------+--------+
accounts:
+-----------+-----------+
| aid | type |
+-----------+-----------+
| 1 | Checkings |
| 2 | Savings |
| 3 | Checkings |
| 4 | CD |
| 5 | CD |
| 6 | Checkings |
+-----------+-----------+
transactions:
+--------+--------+--------+
| tid | cid | aid |
+--------+--------+--------+
| 1 | 1 | 1 |
| 2 | 1 | 2 |
| 3 | 2 | 3 |
| 4 | 3 | 4 |
| 5 | 1 | 5 |
| 6 | 3 | 4 |
| 7 | 1 | 6 |
+--------+--------+--------+
The expected answer would be:
a, 3
b, 1
c, 1
Getting the names is simple enough, but how can I keep count of each individual's account as well as compare the accounts to make sure that it is not the same type?
just add DISTINCT inside the COUNT
SELECT a.cid, a.name, COUNT(DISTINCT c.type) totalCount
FROM customers a
INNER JOIN transactions b
ON a.cis = b.cid
INNER JOIN accounts c
ON b,aid = c.aid
GROUP BY a.cid, a.name
Query:
SQLFiddleExample
SELECT
a."name",
COUNT(DISTINCT c."type") totalCount
FROM customers a
INNER JOIN transactions b
ON a."cid" = b."cid"
INNER JOIN accounts c
ON b."aid" = c."aid"
GROUP BY a."cid", a."name"
ORDER BY totalCount DESC
Result:
| NAME | TOTALCOUNT |
---------------------
| a | 3 |
| b | 1 |
| c | 1 |