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.
Related
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.
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.
I need to join multiple tables in access.
Access has some odd syntax when it comes to joins, and I cant seem to get this right
In particular, C needs to consider fields from both A and B
select a.*, B.*, c.*
from
(tblOne as A
Left join tblTwo as B on A.ParentId = B.Id )
left join tblThree as C on C.ParentId = B.Id and C.ShoeSize = A.ShoeSize
I have encountered and gotten past putting each Parens thing when more than 2 tables are involved.
I can join in C as long as I only want to refer to 1 of the other tables.
This type thing is fairly straight forward in SQL Server.
Any help would be appreciated, I cant seem to find an answer on google.
The client is currently using ms Access 2003. If the problem can be remedied by a newer version, I am pretty I could talk them into an upgrade.
thanks
greg
I just tried the following in Access 2010 and it seems to work, although I must admit that I don't have a clear picture in my mind as to how this might be used in the "real world"...
SELECT ab.*, c.*
FROM
(
SELECT a.ID AS ID1, a.ShoeSize AS ShoeSize1, b.ID AS ID2
FROM tblOne a LEFT JOIN tblTwo b
ON a.ParentId = b.Id
) ab LEFT JOIN tblThree c
ON c.ParentId = ab.ID2 and c.ShoeSize = ab.ShoeSize1
given 3 tables a : {id, name_eng}, b: {id, name_spa} and c: {id, name_ita}
which is the equivalent "product cartesian query" for this given one:
select
a.name_eng
b.name_spa
c.name_ita
from
a inner join b on a.id = b.id
left outer join c on a.id = c.id
I don't know what you want, a cartesian product would be this:
SELECT a.name_eng
b.name_spa
c.name_ita
FROM a
CROSS JOIN b
CROSS JOIN c
Or the implicit way:
SELECT a.name_eng
b.name_spa
c.name_ita
FROM a,b,c
If you want your previous query written with cartesian products (why??), then this should do (on SQL Server 2000):
SELECT a.name_eng
b.name_spa
c.name_ita
FROM a,b,c
WHERE a.id = b.id
AND a.id *= c.id
If I wasn't clear enough with the "why??", you shouldn't use implicit joins since hey are deprecated, you should always use proper explicit joins.
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