SQL: Showing data from two tables together - sql

I'm just starting in the SQL world, so I have a very noob question:
I have 2 tables:
clients (columns: client_id and name)
accounts (columns: account_id and client_id)
and I need to write a query that shows the accounts of all the clients.
But, the problem is that not all the clients have accounts, if the client doesn't have one: how can I show the client_id, the name and NULL for the account_id column?

This query should work:
SELECT *
FROM accounts
LEFT [OUTER] JOIN clients
ON accounts.client_id = clients.client_id;
if not try this one:
SELECT *
FROM accounts
LEFT [OUTER] JOIN clients
ON accounts.client_id = clients.client_id WHERE clients.client_id IS NOT NULL;
These are plain SQL queries, I mean they are not PL-SQL specific. LEFT [OUTER] JOIN will only returns the columns of accounts table. [OUTER] keyword is optional, it defers from database version to version. ON accounts.client_id = clients.client_id will match client_id columns in both tables. Lastly, WHERE clients.client_id IS NOT NULL part should prevent the rows with NULL values in client_id cells.
Useful link: https://www.techonthenet.com/oracle/joins.php

Try this query it returns the clients name client id and shows null to those client who has no accountid.
select clients.name, accounts.account_id from accounts left join clients on
accounts.clintid=clients.client_id

Related

How to join 4 tables in SQL?

I just started using SQL and I need some help. I have 4 tables in a database. All four are connected with each other. I need to find the amount of unique transactions but can't seem to find it.
Transactions
transaction_id pk
name
Partyinvolved
transaction.id pk
partyinvolved.id
type (buyer, seller)
PartyCompany
partyinvolved.id
Partycompany.id
Companies
PartyCompany.id pk
sector
pk = primary key
The transaction is unique if the conditions are met.
I only need a certain sector out of Companies, this is condition1. Condition2 is a condition inside table Partyinvolved but we first need to execute condition1. I know the conditions but do not know where to put them.
SELECT *
FROM group
INNER JOIN groupB ON groupB.group_id = group.id
INNER JOIN companies ON companies.id = groupB.company_id
WHERE condition1 AND condition2 ;
I want to output the amount of unique transactions with the name.
It is a bit unclear what you are asking as your table definitions look like your hinting at column meanings more than names such as partycompany.id you are probably meaning the column that stores the relationship to PartyCompany column Id......
Anyway, If I follow that logic and I look at your questions about wanting to know where to limit the recordsets during the join. You could do it in Where clause because you are using an Inner Join and it wont mess you your results, but the same would not be true if you were to use an outer join. Plus for optimization it is typically best to add the limiter to the ON condition of the join.
I am also a bit lost as to what exactly you want e.g. a count of transactions or the actual transactions associated with a particular sector for instance. Anyway, either should be able to be derived from a basic query structure like:
SELECT
t.*
FROM
Companies co
INNER JOIN PartyCompancy pco
ON co.PartyCompanyId = pco.PartyCompanyId
INNER JOIN PartyInvolved pinv
ON pco.PartyInvolvedId = pinv.PartyInvolvedId
AND pinv.[type] = 'buyer'
INNER JOIN Transactions t
ON ping.TransactionId = t.TransactionId
WHERE
co.sector = 'some sector'

Explain what means to join same table twice

I was preparing for exam and I have this exercise that I don't understand
I have table of Clients that have ClientID,
and also I have table of Transactions that have Foreign Key referenced to Clients, SenderID and RecieverID (refering to ClientID)
I need to create view that will show Transactions with Sender name and Reciever Name, and I did it but I don't understand how it works and why
Here is code:
SELECT CS.Name [SenderName], CR.Name [RecieverName]
FROM Transactions T
INNER JOIN Clients CS
ON CS.ClientID = T.SenderID
INNER JOIN Clients CR
ON CR.ClientID = T.RecieverID
Each time you need the name (for sender or recevier ) you need a relation based on the key between the the transaction table and the clients table
you need the name of the sender ( first join with Clients ) and the name for recevier ( second join with Clients )
for avoid confusion between the two (same name) table you need an alias that let you join the specific related tabe .. you use CS and CR as table nale alias
in this way is as you work with two differente table name (or with a logical duplication of the same table)
SELECT CS.Name [SenderName], CR.Name [RecieverName]
FROM Transactions T
INNER JOIN Clients CS ON CS.ClientID = T.SenderID
INNER JOIN Clients CR ON CR.ClientID = T.RecieverID
You can thinks at the table content as a set of data ..so you use two time the same set of data extracting the row mathcing your relation each time.
Each row in the table Transactions contains:
a SenderID which points to a row in the table Clients and
a RecieverID which points to another row in the table Clients.
So you must make one join of Transactions to Clients using SenderID to get the sender's name and another join to Clients using RecieverID to get the reciever's name.

SQL fetch multiple values on join

Hi I have an SQL table which has two tables which make reference to the same foreign key in a separate table twice... something like
SALES table
idSales idClient1 idClient2
1 1 2
CLIENT table
idClient ClientName
1 Bob
2 Mick
I want to join the SALES table to the CLIENT table and return data as follows:
idSales idClientClientName1 idClientClientName2
1 Bob Mick
Can anyone help with the SQL for this? I'm getting ambiguous column name errors on my join.
Thank you
You need to basically join table Client on table Sales twice because there are two columns on table Sales that are dependent on table Client.
SELECT a.idSales,
b.ClientName ClientName1,
c.ClientName ClientName2
FROM Sales a
INNER JOIN Client b
ON a.idClient1 = b.idClient
INNER JOIN Client c
ON a.idClient2 = c.idClient
To further gain more knowledge about joins, kindly visit the link below:
Visual Representation of SQL Joins
But when one of the columns or both columns are nullable, INNER JOIN will not give you all records from Sales because it will only select where it has atleast one match on the other table. Instead use LEFT JOIN.
I might add that in cases like this, I use table aliases that hint at what entity you are linking to in the joined table. If for example, the foreign keys were to an address table, and you had a work address, and a Home address, I would use tables aliases of h and w for the two joins. In your case, i.e.,
Selext s.idSales,
c1.ClientName ClientName1,
c2.ClientName ClientName2
From Sales s
Join Client c1
On c1.idClient = s.idClient1
Join Client c2
On c2.idClient = s.idClient2
For those beginner SQL folks who may see this question in the future, it's helpful to add in the AS words, it makes it clearer still:
SELECT
Sale.idSales,
c1.ClientName AS ClientName1,
c2.ClientName AS ClientName2
FROM
Sales AS Sale
INNER JOIN Client AS c1 ON Sale.idClient1 = c1.idClient
INNER JOIN Client AS c2 ON Sale.idClient2 = c2.idClient

Get an array in a field after a JOIN

Let's say that I have a table called Appointments, another called Clients and a joining table called ClientsAppointments which relates the two aforementioned ones. This is used in a scenario where a client can have several appointments, and several clients can attend to the same appointment (n-n relation).
I would like to list the Appointments with a field "clients" being an array of all the Clients related to that appointment. What I've tried so far:
SELECT * FROM Appointments a
INNER JOIN ClientsAppointments ca ON ca.IdAppointment = a.IdAppointment
INNER JOIN Clients c ON c.IdClient = ca.IdClient
That doesn't work, of course. It gives me a list of appointments repeated with each of the clients they have. Then in PHP I would process them to achieve this. It seemed more efficient this way rather than making multiple queries because there's usually only one client per appointment.
Table schema (these are not the actual tables, but simplified to illustrate the case):
Appointment(
INT idAppointment,
DATETIME start,
DATETIME end)
Clients(
INT idClient,
VARCHAR name)
ClientsAppointments(
INT idAppointment,
INT idClient)
If you use MySQL as a database try to use GROUP_CONCAT:
SELECT a.IdAppointment,GROUP_CONCAT(CAST(ca.IdClient AS CHAR) SEPARATOR ',') FROM Appointments a
INNER JOIN ClientsAppointments ca ON ca.IdAppointment = a.IdAppointment
group by a.IdAppointment
Try to use LEFT OUTER JOIN
SELECT a.*,c.Name FROM ClientsAppointments ca
LEFT OUTER JOIN Appointments a ON ca.IdAppointment = a.IdAppointment
LEFT OUTER JOIN Clients c ON ca.IdClient = c.IdClient

New to SQL. Query SQL database using info across three tables

This is using phpMyAdmin.
I need to find the contact information for Subscribers who have pending Orders on November 15th. Their contact information is stored in a table called Subscribers, and the primary key is UID (User ID). The Subscriptions Table has a primary key called SID (Subscriptions ID). The Subscriptions table also stores the UID for each Subscription. However, the Orders table is where the Date is stored, and this table stores the SID but not the UID, so I can't directly JOIN Orders with Subscribers.
I have to JOIN Orders with Subscriptions on SID where the Orders Date is 11-15-10, and then I have to JOIN the resulting table with the Subscribers table on UID.
I'm currently trying this:
SELECT * FROM Subscribers
RIGHT JOIN (Orders a, Subscriptions b, Subscribers c)
ON (a.SID = b.SID AND b.UID = c.UID)
WHERE a.Date = '2010-11-01'
This is causing a massive lag followed by Gateway Timeout.
This is a classic case of knowing what to do, but not knowing how to do it. Any help would be greatly appreciated. Thanks!
You could try this:
SELECT
scrb.*
FROM
Subscribers scrb
WHERE
scrb.UID in (
SELECT DISTINCT
scrp.UID
FROM
Subscriptions scrp
INNER JOIN Orders ordr ON
ordr.SID = scrp.SID
WHERE
ordr.Date = STR_TO_DATE('2010-11-01')
)
Not sure if you're going to have a big performance improvement though... Maybe your tables miss a better indexing strategy...?
In fact, you should try executing just the inner query (SELECT DISTINCT scrp.UID...) first... If it is too slow, I would guess your problem is on the Orders.Date field - a full scan over that table probably has a high performance cost.
Why do you join Subscribers to Subscribers?
SELECT * FROM Subscribers ... JOIN ... Subscribers c)
Given the limited amount we know about your schema, it seems like you'd do better with an INNER JOIN, which will filter records for you, and #seriyPS is right about the redundant Subscribers table - currently, this query as written is performing a CROSS JOIN, joining all Subscribers to every result of Subscriber joined to Subscription joined to Order...
Is there a reason why this won't work?
SELECT a.*
FROM Subscribers a
INNER JOIN Subscriptions b ON a.UID = b.UID
INNER JOIN Orders c ON b.SID = c.SID
WHERE c.Date = '2010-11-01'