SQL 3 tables (long time ago) - sql

I haven't done a SQL statement in about 10 years. A little help?
Table A:
ID, Title
1,"hello"
2,"world"
Table B:
ID, OBJ_ID
1,23
2,24
Table C:
ID, Name
23,"foo"
23,"bar"
24,"hi"
24,"pangea"
A.ID = B.ID
B.OBJ_ID = C.ID
One (A) to One (B) to Many (C)
Result needed:
A.Title, C.Name(s)
hello,foo,bar
world,hi,pangea
Thanks.
I know I'm flat out asking for answer, but which JOIN would I use? Thanks.
MariaDB, I'm trying to extract some data from someone's WP site. Why table B is there, is beyond me.

Thanks #jarlh
select a.title, c.name
from c
join b on b.obj_id = c.id
join a on a.id = b.obj_id

SELECT A.Title, C.Name
FROM A join B on A.ID=B.ID JOIN C ON B.ID=C.ID
ORDER BY A.Title, C.Name
If you want to have one row per title with all values from table C, consider using pivot.

Related

SQL - Searching a table using another table's column as criteria

I have table B with bcust(4-digit integer) and bdate(date) columns. I also have table C with ccust(4-digit integer) and cdate(date). I want to show the records from table c where cdate occurred after bdate.
I guess, maybe you're looking for this?
SELECT c.*
FROM c
INNER JOIN b
ON b.bcust = c.ccust
AND b.bdate < c.cdate;
I assumed, that the records are linked via the bcust and ccust columns.
Although you did not mention anything on how the records in both tables are related, I guess that records are related if bcust = ccust.
Then something like this should do what you want:
SELECT c.*
FROM tableC c
INNER JOIN tableB b ON c.ccust = b.bcust
WHERE c.cdate > b.bdate

Same ID field on multiple tables

So I've been given a task where i should present the following:
ID, LNAME, FNAME, MNAME, BIRTH_DATE, RELG_CODE, NAT_CODE, PT_STATUS, RM_NO, DTTM_ADM
The tables are:
HISR_CODES, PASR_NAMES, PASR_PROFILE, PAST_PATIENT_ADM
--Viewing them using DESC--
So while I viewed them, I was told that the ID on these tables are the same. So what I did so far in the coding (I'll finish the rest but I need to make sure this works first):
SELECT
A.ID,
A.LNAME,
A.FNAME,
A.MNAME,
A.BIRTH_DATE,
C.RELG_CODE,
C.NAT_CODE,
B.PT_STATUS,
B.RM_NO,
B.DTTM_ADM
FROM
PASR_NAMES A,
PASR_PROFILE B,
PAST_PATIENT_ADM C,
HISR_CODES D
WHERE
A.ID = B.ID
AND
B.ID = C.ID
AND
C.ID = D.ID
Is there a way to tell that all of the ID's from the tables are the same? A simpler code than going on like this:
WHERE
A.ID = B.ID
AND
B.ID = C.ID
AND
C.ID = D.ID
Or is JOIN - ON the only option for this?
You can use NATURAL JOIN as below:
SELECT
A.ID,
A.LNAME,
A.FNAME,
A.MNAME,
A.BIRTH_DATE,
C.RELG_CODE,
C.NAT_CODE,
B.PT_STATUS,
B.RM_NO,
B.DTTM_ADM
FROM
PASR_NAMES A
NATURAL JOIN PASR_PROFILE B
NATURAL JOIN PAST_PATIENT_ADM C
NATURAL JOIN HISR_CODES D;
From Oracle Reference, "A natural join is based on all columns in the two tables that have the same name." So, there is a chance that the joins happen based on other columns as well. Therefore, it is recommended that you still use the INNER JOIN syntax and explicitly specify the JOIN columns.
References:
NATURAL JOIN on Oracle® Database SQL Language Reference
Related SO question
Use the proper join syntax:
FROM PASR_NAMES A JOIN
PASR_PROFILE B
ON A.ID = B.ID JOIN
PAST_PATIENT_ADM C
ON B.ID = C.ID JOIn
HISR_CODES D
ON C.ID = D.ID
Or:
FROM PASR_NAMES A JOIN
PASR_PROFILE B
USING (ID) JOIN
PAST_PATIENT_ADM C
USING (ID)
HISR_CODES D
USING (ID)
I would discourage you from using the natural join. It might seem like the right thing at first. However, the semantics of the query are highly dependent on the structure of the tables. If columns are renamed, removed, or added, the query might still work but produce highly unexpected results.

SQL SELECT and SUM from three

I have been cracking my head for hours on what I thought to be simple SQL SELECT command. I searched every where and read all questions related to mine. I tried an SQL Command Builder, and even read and applied complete series of SQL tutorials and manuals to try to build it from scratch understanding it (which is very important for me, regarding next commands I'll eventually have to build...).
But now I'm just stuck with the results I want, but on separates SELECT commands which I seem to be unable to get together !
Here is my case : 3 tables, first linked to the second with a common id, second linked to the third with another common id, but no common id from the first to the third. Let's say :
Table A : id, name
Table B : id, idA, amount
Table C : id, idB, amount
Several names in Table A. Several amounts in Table B. Several amounts in Table C. Result wanted : each A.id and A.name, with the corresponding SUM of B.amount, and with the corresponding SUM of C.amount. Let's say :
A.id
A.name
SUM(B.amount) WHERE B.idA = A.id
SUM(C.amount) WHERE C.idB = B.id for each B which B.idA = A.id
It's okay for "the first three columns", and "the first two columns and the fourth", both with a WHERE clause and/or a LEFT JOIN. But I can't achieve cumulating all fourth columns together without messing everything !
One could say "it's easy, just put an idA column in Table C" ! Should be easier, sure. But is it really necessary ? I don't think so, but I could be wrong ! So, I just please anyone (who I will give an eternal "SQL God" decoration) with SQL skills to answer laughing "That's so simple ! Just do that and you are gone ! Stupid little newbies..." ;)
Running VB 2010 and MS SQL Server
Thanks for reading !
Try this:
SELECT A.Id, A.Name, ISNULL(SUM(B.amount), 0) as bSum, ISNULL(SUM(C2.Amount), 0) as cSum
FROM A
LEFT OUTER JOIN B ON A.Id = B.idA
LEFT OUTER JOIN (SELECT C.idB, SUM(C.AMOUNT) AS Amount FROM C GROUP BY C.idB) AS C2 ON C2.idB = B.Id
GROUP BY A.Id, A.Name
Try this:
SELECT
a.id,
a.name,
sum(x.amount) as amountb,
sum(x.amountc) as amountc
from a
left join (
select
b.id,
b.ida,
b.amount,
SUM(c.amount) as amountc
from b
left join c
on b.id = c.idb
group by
b.id,
b.amount,
b.ida
) x
on a.id = x.ida
group by
a.id,
a.name
This should give you the result set you're looking for. It sums all C.Amount's for each B.id, then adds it all together into a single result set. I tested it with a bit of sample data in MSSQL, and it works as expected.
Select a.id, a.name, sum(b.amount), sum(c.amount)
from a inner join b on a.id = b.idA
inner join c on b.id = c.idB
group by a.id, a.name
You need to add them separately:
select a.id, a.name, (coalesce(b.amount, 0.0) + coalesce(c.amount, 0.0))
from a left outer join
(select b.ida, sum(amount) as amount
from b
group by b.ida
) b
on a.id = b.ida left outer join
(select b.ida, sum(amount) as amount
from c join
b
on c.idb = b.id
group by b.ida
) c
on a.id = c.ida
The outer joins are to take into account when b and c records don't both exist for a given id.

Use Join to get record info without returning the row in the query

I have two tables (Apple and Bid). I want to return all rows from A based on a given condition, and I want to get a single value from table B. It will help if I show what I'm trying to do:
Apple
ID
Name
Type
Bid
bid_id
Type
I want to return all records from A where the ID matches a given ID AND I want to get the bid_id associated with each record pulled from table A.
So, my query looks something like this:
"Select A.ID, A.Name, A.Type, B.bid_id
FROM Apple A
LEFT JOIN Bid B on B.Type = A.Type
Where A.ID = 35";
There is only one record in the Apple table with an id of 35. However, since there are three tables in the Bid table whose type matches that of Apple # 35's type, three records are being returned.
To clarify, only one record should be being returned.
Any ideas?
For MySQL:
Select A.ID, A.Name, A.Type, B.bid_id
FROM Apple A
LEFT JOIN Bid B
ON B.Type = A.Type
WHERE A.ID = 35
GROUP BY A.ID
That will return one of the bid_id's. If you have some rule as to which bid_id to choose, you can implement it using aggregation functions - e.g., MIN, MAX, and more complex rules can be implemented as well.
Arbitrarily choosing to return the MIN value:
Select A.ID, A.Name, A.Type, MIN(B.bid_id)
FROM Apple A
LEFT JOIN Bid B
ON B.Type = A.Type
WHERE A.ID = 35
GROUP BY A.ID, A.Name, A.Type;
Given that you're looking for up to one random bid, the fastest option would be limit 1:
select A.ID
, A.Name
, A.Type
, B.bid_id
from Apple A
left join
Bid B
on B.Type = A.Type
where A.ID = 35
limit 1

Joining One table to many using Joins

In this question it's finally clicked how to write joins between multiple tables, where they link in a line e.g.
Table A - Table B - Table C
Where Table A references Table B, and Table B references Table C and so on.
What I still don't understand is how to reference the situation where Table A references Table B as above and also reference Table D.
In implicit Joins I can get the following to work, but want to move it to explicits...
SELECT a.name, b.office, c.firm, d.status
FROM job a, depts b, firms c, statuses d
WHERE a.office = b.ref
AND b.firm = c.ref
AND a.status = d.ref
Any tips?
SELECT
a.name,
b.office,
c.firm,
d.status
FROM
job a
JOIN depts b ON a.office = b.ref
JOIN firms c ON b.firm = c.ref
JOIN statuses d ON a.status = d.ref
That's as detailed as I could get on such an obscure question. You didn't describe what exactly does "link" mean in your case. So I don't know, maybe you need left join.