sql select statement with a group by - sql

I have data in 2 tables, and I want to create a report.
Table A:
tableAID (primary key)
name
Table B:
tableBID (primary key)
grade
tableAID (foreign key, references Table A)
There is much more to both tables, but those are the relevant columns.
The query I want to run, conceptually, is this:
select TableA.name, avg(TableB.grade) where TableB.tableAID = TableA.tableAID
The problem of course is that I'm using an aggregate function (avg), and I can rewrite it like this:
select avg(grade), tableAID from TableB group by tableAID
but then I only get the ID of TableA, whereas I really need that name column which appears in TableA, not just the ID.
Is it possible to write a query to do this in one statement, or would I first need to execute the second query I listed, get the list of id's, then query each record in TableA for the name column... seems to me I'm missing something obvious here, but I'm (quite obviously) not an sql guru...

You can do this:
SELECT avg(b.grade), a.tableAID, a.name
FROM TableA a
JOIN TableB b
ON b.tableAID = a.tableAID
GROUP BY a.tableAID, a.name
Just adding it to the group will work fine in your case.

SELECT AVG(TableB.grade), TableB.tableAID, TableA.Name
FROM TableA INNER JOIN TableB
ON TableA.TableAID = TableB.TableAID
GROUP BY TableA.tableAID, TableA.Name

Alternative answer:
SELECT AVG(b.grade), a.tableAID, MAX(a.name )
FROM TableA a
JOIN TableB b
ON b.tableAID = a.tableAID
GROUP BY a.tableAID
Just to get you thinking.

Related

Join of Two Tables where Data Matches in One Column

For some reason I have a hard time grasping joins and this one should be very simple with the knowledge that I have in SQL.
Anyway, I have 2 tables. We will call them TableA and TableB. One of the columns in TableA is "ID". TableB only consists of the column "ID". I want to return all rows in TableA whose ID is present in TableB.
I know this should be very simple to figure out, but my brain doesn't want to work today.
You can do this using an EXISTS:
Select A.*
From TableA A
Where Exists
(
Select *
From TableB B
Where A.Id = B.Id
)
You can also use a JOIN if you wish, but depending on your data, you may want to couple that with a SELECT DISTINCT:
Select Distinct A.*
From TableA A
Join TableB B On A.Id = B.Id
One thing to keep in mind is that the ID of TableA is not necessarily related to the ID of TableB.
this should work
SELECT B.ID
FROM TableA A
JOIN TableB B
ON (A.ID=B.ID)
WHERE A.ID=B.ID
You can also use IN operator like this:
Select *
From TableA
Where ID in
(
Select distinct ID
From TableB
)

SQL Where Condition with IF Statement

So I'm trying to write a query to pull some data and I have one condition that needs to be met and I can't seem to figure out how to actually execute it. What I'm trying to achieve is that if a column is not null in one table, then I want to check another table and see if there is a specific value in one those columns. So in a psuedo code type of way I'm trying to do this
SELECT id, user_name, created_date, transaction_number
FROM TableA
WHERE (IF TableA.response_id IS NULL OR
IF (SELECT type_id from TableB WHERE (type_id NOT IN ('4)) AND (id = TableA.response_id))
So from here what I'm trying to do is pull all transactions for customers that have no responses in them, but from those that do have responses I still want to grab transaction that's don't have a specific code associated to them. I'm not sure if it's possible to do it in this manner or if I need to create some temporary tables that can then be manipulated but I'm stuck on this one condition.
At first I thought you wanted the CASE statement from the wording of your question, but I think you're just looking for an OUTER JOIN with an OR statement:
SELECT DISTINCT a.id, a.user_name, a.created_date, a.transaction_number
FROM TableA A
LEFT JOIN TableB B ON A.response_id = B.Id
WHERE A.response_id IS NULL
OR B.type_id NOT IN (4)
A Visual Explanation of SQL Joins
where TableA.Response_id is null or (select count(1) from TableB WHERE (type_id NOT IN ('4)) AND (id = TableA.response_id)) = 0
provided that your subquery is logically correct.
Well I'm not 100% certain I follow, but assuming what you want is to see if there are response entries for a particular ID in Table A I think you want something like this.
SELECT a.id, user_name, created_date, transaction_number
FROM TableA a
LEFT JOIN TableB b
ON a.id=b.id
LEFT JOIN TableC c
ON a.id=c.id
WHERE isnull(b.id,c.id) IS NOT NULL
GROUP BY a.id, user_name, created_date, transaction_number
ISNULL will return b.id if it is not null, c.id if c.id is not null and NULL otherwise. That will tell you if there's a response for a.id in either TableB or TableC. That's assuming TableB & TableC are more like logs. If you're saying those table will certainly have an entry for a.id then it's just a matter of replacing b.id & c.id with b.[response_column] & c.[response_column] respectively.

Oracle SQL Conditional Outer Join using case statement

Lets say that I have three tables:
1. TableA with columns TableAID (PK), Desc Nullable
2. TableB with columns TableBID (PK), TableAID(FK) Nullable
3. TableC with columns TableCID (PK), TableBID (FK) Nullable,
TableAID (FK) Nullable, Start_Date, End_Date
I need to return the Desc in Table A
if TableC.TableBID is not null then use the TableAID(FK) in TableB to retrieve Desc
else
use TableAID (FK) in TableC to retrieve Desc
Note: It's possible both TableC.TableBID or TableC.TableAID can be null. In all cases I still must be able to return the other columns in TableC.
Here is my code:
Select ta.desc, tc.start_date, tc.end_date
from TableC tc
Left outer join TableB tb
on case
when tc.TableBID is not null then (
tc.TableBID = tb.TableBID
Left outer join TableA ta
on tb.TableAID = ta.TableAID
--my concern here is that tb.TableAID can be null. Will it still work?
)
else tc.TableAID = ta.TableAID --my concern here is that tc.TableAID can be null.
--WIll it still work?
I'm also concern about syntax. If there is a better way to have a conditional join, please advise. I'm using oracle. This code will go into a view which will be used for a search procedure (that's why it has to return everything regardless of nulls).
Thanks for your help.
You can put your CASE in the SELECT clause and join the tables accordingly, like this:
SELECT CASE
WHEN tb.tableAID IS NOTNULL THEN tab.desc
ELSE tac.desc
END AS desc
-- or better: NVL(tab.desc, tac.desc) AS desc
, tc.start_date
, tc.end_date
FROM tableC tc
JOIN tableB tb ON tc.tableBID = tb.tableBID
LEFT JOIN tableA tab ON tab.tableAID = tb.tableAID
LEFT JOIN tableA tac ON tac.tableAID = tc.tableAID

SQL select statement ORDER BY relationship to a second table?

I have table A, which contains a row for an int representing the table B object they relate to.
Multiple As can reference the same B. B does not reference A
I want to return As ordered by a row in the B object they relate to.
Is there a way to do this in one SQL statement? Or even 2?
Thank you.
You can put anything in your SELECT list and ORDER BY any column you'd like as long as it's in tablea or tableb
SELECT a.ID
FROM tablea
INNER JOIN tableb ON tablea.ID = tableb.ID
ORDER BY tableb.ID
Have you tried using
Select (columns that you want to display)
from TableA INNER JOIN TableB
ON TableA.col = TableB.col
Order By TableB.ColumnName

SQL join, getting multiple columns with same name

I have one table with a column ID and SERVICE_TYPE_TEXT, and another table with columns
ID, SERVICE_TYPE ...
and lots of other columns.
The SERVICE_TYPE in the second table contains the ID from the first table. I want to query so I can get the SERVICE_TYPE_TEXT from the first table that matches the ID given in the second table.
I've tried to join, and setting different names on ID with AS, but always at the end of the query result I get the original ID from the first table with column name ID, as well as the name I defined in the AS.
Any suggestions on how I can get the ID from the first table to stay away ? :)
Try something like this,
SELECT a.ID AS ServiceID,
a.Service_Type_Text,
b.ID AS table2ID,
b.Service_Type
FROM table1 a
INNER JOIN table2 b
ON a.ID = b.Service_Type
Set your query so that it returns all data from the second table but only the required field (column) from the first.
Something like this:
SELECT TAB1.SERVICE_TYPE_TEXT, TAB2.*
FROM TAB1
INNER JOIN
TAB2
ON TAB1.ID = TAB2.SERVICE_TYPE
TRY
SELECT a.ID AS ServiceID,
a.Service_Type_Text,
b.ID AS table2ID,
b.Service_Type
FROM table1 a
INNER JOIN table2 b
ON a.ID = b.Service_Type AND b.ID='YOUR_ID';