I have recently started learning SQL but can't seem to get my head around creating SQL statements that form relevant results from multiple tables/relations.
Given the following schema:
Account(accNumber, balance, type)
Branch(BSB, phone, streetAddress, town)
registered(accNumber*, BSB*)
I am trying to formulate some outputs:
List all the accNumber registered with a specific BSB (123) and show its listed town (Sydney).
I have tried the following statement for the first query:
SELECT accNumber, BSB, town
FROM ACCOUNT, BRANCH
WHERE BSB = 123;
However, I get every account listed even if they don't belong to the BSB, so I tried:
SELECT accNumber, BSB, town
FROM ACCOUNT, BRANCH
WHERE BSB = 123
AND Town = 'Sydney'
AND account.accNumber=registered.accNumber
AND branch.bsb=registered.bsb;
This time I get column ambiguously defined because they have the same name in the "registered" table.
I've tried making alias in the select statment i.e. accNumber AS ACCOUNT_NUMBER etc, but still getting ambiguously defined errors.
I tried just listing what was in the registered table but then I do not get the town name, just the accNumber and the BSB passed in as a foreign key.
I can't seem to understand how to pull data from other tables and display them correctly and would greatly appreciate any advice!
This might help you start.
SELECT a.ccNumber, b.BSB, c.town
FROM ACCOUNT as a
inner join registered as b on b.accNumber=a.accNumber
inner join BRANCH as c on c.bsb = b.bsb
WHERE b.BSB = 123
AND c.Town = 'Sydney'
So this sounds like a generic SQL question. For your query here is what you're looking at:
select a.account_number
from account a, brance b, registered r
where a.account_number = r.account_number and
a.bsb = b.bsb and
b.bsb = 123;
This will get you all account numbers from the account table that are in BSB 123. When you have multiple tables that have the same column, you need to tell Oracle (and any database for that matter) which "account_number" column you're referring to (as otherwise it's ambiguous as there are multiple tables that contain the column account_number).
SQL is about tables and joins. You sometimes have to join several tables to get what you need, as above. If you don't join tables, as you did originally, you'll get a "cross product", which is not what you want.
I know this is very "light", but hopefully from the above answer to your question, you'll get some idea of how to do this.
I'd be happy to help you more if you have questions. Everyone is new to SQL at some point. Don't feel bad about that. It takes practice and then it becomes much easier.
-Jim
Related
Made this account just to ask about this question after being unable to find/expending the local resources I have, so I come to you all.
I'm trying to join two tables - ORDERS and CUSTOMER - as per a question on my assignment
For every order, list the order number and order date along with the customer number, last name, and first name of the customer who placed the order.
So I'm looking for the order number, date, customer number, and the full name of customers.
The code goes as such
SELECT ORDERS.ORDR_ORDER_NUMBER, ORDERS.ORDR_ORDER_DATE, ORDERS.ORDR_CUSTOMER_NUMBER, CUSTOMER.CUST_LAST, CUSTOMER.CUST_FIRST
FROM ORDERS, CUSTOMER
WHERE ORDERS.ORDR_CUSTOMER_NUMBER = CUSTOMER.CUST_CUSTOMER_NUMBER;
I've done this code without the table identifiers, putting quotation marks around ORDERS.ORDR_CUSTOMER_NUMBER, aliases for the two tables, and even putting a space after ORDR_ in both SELECT & WHERE for laughs and nothing's working. All of them keep coming up with the error in the title (ORA-00904), saying [ORDERS.]ORDR_CUSTOMER_NUMBER is the invalid identifier even though it shouldn't be.
Here also are the tables I'm working with, in case that context is needed for help.
Anyway, the query that produces the result you want should take the form:
select
o.ordr_order_number,
o.ordr_order_date,
c.cust_customer_number,
c.cust_last,
c.cust_first
from orders o
join customer c on c.cust_customer_number = o.ordr_customer_number
As you see the query becomes a lot easier to read and write if you use modern join syntax, and if you use table aliases (o and c).
You have to add JOIN or INNER JOIN to your query. Because the data comes from two different tables the WHERE clause will not select both.
FROM Orders INNER JOIN Customers ON Orders.order_Customer_Number = Customer.Cust_Customer_Number
I currently have three tables.
master_tradesmen
trades
master_tradesmen_trades (joins the previous two together in a many-to-many relationship). The 'trade_id' and 'master_tradesman_id' are the foreign keys.
Here is what I need to happen. A user performs a search and types in a trade. I need a query that displays all of the information from the master_tradesmen table whose trade in the master_tradesmen_trade table matches the search. For example, if 'plumbing' is typed in the search bar (trade_id 1), all of the columns for Steve Albertsen (master_tradesman_id 6) and Brian Terry (master_tradesman_id 8) would be displayed from the master_tradesmen table. As a beginner to SQL, trying to grasp the logic of this is about to make my head explode. I'm hoping that someone with more advanced SQL knowledge can wrap their head around this much easier than I can. Note: the 'trades' column in master_tradesmen is for display purposes only, not for querying. Thank you so much in advance!
You have a catalog for the tradesmen, & another catalog for the trades.
The trades should only appear once in the trades catalog in order to make your DB more consistent
Then you have your many-to-many table which connects the trades & master tradesmen tables.
If we want to get the tradesmen according to the given trade in the input, we should first
know the id of that trade which has to be unique, so in your DB you would have something
like the img. below :
Now we can make a query to select the id of trade :
DECLARE #id_trade int = SELECT trade_id FROM trades WHERE trade_name LIKE '%plumbing%'
Once we know the trading id, we can redirect to the 'master_tradesmen_trades' table to know the name of the people how work that trade :
SELECT * FROM master_tradesmen_trades WHERE trade_id = #id_trade
You will get the following result :
You may say, 'But there is still something wrong with it, as i am still not able to see the tradesmen', this is the moment when we make an inner join:
SELECT * FROM master_tradesmen_trades trades_and_tradesmen
INNER JOIN master_tradesman tradesmen
ON tradesmen.id = trades_and_tradesmen.master_tradesmen_id
WHERE trade_id = #id_trade
IF you need to see specific columns, you can do :
SELECT first_name, last_name, city, state FROM master_tradesmen_trades trades_and_tradesmen
INNER JOIN master_tradesman tradesmen
ON tradesmen.id = trades_and_tradesmen.master_tradesmen_id
WHERE trade_id = #id_trade
Good morning/afternoon! I was hoping someone could help me out with something that probably should be very simple.
Admittedly, I’m not the strongest SQL query designer. That said, I’ve spent a couple hours beating my head against my keyboard trying to get a seemingly simple three way join working.
NOTE: I'm querying a Vertica DB.
Here is my query:
SELECT A.CaseOriginalProductNumber, A.CaseCreatedDate, A.CaseNumber, B.BU2_Key as BusinessUnit, C.product_number_desc as ModelNumber
FROM pps_sfdc.v_Case A
INNER JOIN reference_data.DIM_PRODUCT_LINE_HIERARCHY B
ON B.PL_Key = A.CaseOriginalProductLine
INNER JOIN reference_data.DIM_PRODUCT C
ON C.product_line_code = A.CaseOriginalProductLine
WHERE B.BU2_Key = 'XWT'
LIMIT 20
I have a view (v_Case) that I’m trying to join to two other tables so I can lookup a value from each of them. The above query returns identical data on everything EXCEPT the last column (see below). It's like it's iterating through the last column to pull out the unique entries, sort of like a "GROUP BY" clause. What SHOULD be happening is that I get unique rows with specific "BusinessUnit" and "ModelNumber" for that record.
DUMEPRINT 5/2/2014 8:56:27 AM 3002845327 JJT Product 1
DUMEPRINT 5/2/2014 8:56:27 AM 3002845327 JJT Product 2
DUMEPRINT 5/2/2014 8:56:27 AM 3002845327 JJT Product 3
DUMEPRINT 5/2/2014 8:56:27 AM 3002845327 JJT Product 4
I modeled my solution after this post:
How to deal with multiple lookup tables for beginners of SQL?
What am I doing wrong?
Thank you for any help you can provide.
Data issue. General rule in trouble shooting these is the column that is distinct (in this case C.product_number_desc as ModelNumber) for each record is generally where the issue is going to be...and why I pointed you towards dim_product.
If you receive duplicates, this query below will help identify if this table is giving you the issues. Remember key in this statement can be multiple fields...whatever you are joining the table on:
Select key,count(1) from table group by key having count(1)>1
Other options for the future...don't assume it's your code, duplicates like this almost always point towards dirty data (other option is you are causing cross joins because keys are not correct). If you comment out the 'c' table and the column referred to in the select clause, you would have received one row...hence your dupes were coming from the 'c' table here.
Good luck with it
Hello I have a question regarding a query I am trying to create. I want to create a query that will List members'name for who ever checked out one oe more books and have returned ALL of them. I have a query (shown below that finds the entries if there Return Date is no NULL but I can't figure out how to now show the Names if they have a returned book but still have another book they have no returned (Return Date = NULL). Below is my script if anybody can give me some advice. Thank you.
SELECT MemName
FROM MEMBER, CHECK_OUT
WHERE MEMBER.ID = CHECK_OUT.MemID
AND CHECK_OUT.DateRet IS NOT NULL
If I understand what you are asking, you want a query that will return all members who currently have a book checked out, correct?
Something like this might be what you want:
SELECT
M.MemName
FROM
MEMBER AS M
INNER JOIN CHECK_OUT AS C ON (C.MemID = M.ID)
WHERE
C.DateRet IS NULL
This will list all member names that have something checked out, but will not remove duplicates. To list each name only one, use SELECT DISTINT. To get the names who do NOT have anything checked out anymore (but did at one point) use either your query or modify mine to say C.DateRet IS NOT NULL. I personally just like using INNER JOINS in this situation.
I want to create a query that will List members' names for who ever checked out one or more books and have returned ALL of them.
SELECT MEMBER.MemName
FROM MEMBER, CHECK_OUT
WHERE MEMBER.ID = CHECK_OUT.MemID
group by MEMBER.ID, MEMBER.MemName
having max(nvl2(CHECK_OUT.DateRet, 0, 1)) = 0
Say you have these tables:
PHARMACY(**___id_pharmacy___**, name, addr, tel)
PHARMACIST(**___Insurance_number___**, name, surname, qualification, **id_pharmacy**)
SELLS(**___id_pharmacy___**, **___name___**, price)
DRUG(**___Name___**, chem_formula, **id_druggistshop**)
DRUGGISTSHOP(**___id_druggistshop___**, name, address)
I think this will be more specific.
So, I'm trying to construct an SQL statement, in which I will fetch the data from id_pharmacy and name FROM PHARMACY, the insurance_number, name, and surname columns from PHARMACIST, for all the pharmacies that sell the drug called Kronol.
And that's basically it. I know I'm missing the relationships in the code I wrote previously.
Note: Those column names which have underscores left and right to them are underlined(Primary keys).
The query you've written won't work in any DBMS that I know of.
You'll most likely want to use some combination of JOINs.
Since the exact schema isn't provided, consider this pseudo code, but hopefully it will get you on the right track.
SELECT PH.Ph_Number, PH.Name, PHCL.Ins_Number, PHCL.Name, PHCL.Surname
FROM PH
INNER JOIN PHCL ON PHCL.PH_Number = PH.Ph_Number
INNER JOIN MLIST ON MLIST.PH_Number = PH.PH_Number
WHERE MLIST.Name = "Andy"
I've obviously assumed some relationships between tables that may or may not exist, but hopefully this will be pretty close. The UNION operator won't work because you're selecting different columns and a different number of columns from the various tables. This is the wrong approach all together for what you're trying to do. It's also worth mentioning that a LEFT JOIN may or may not be a better option for you, depending on the exact requirements you're trying to meet.
Ok, try this query:
SELECT A.id_pharmacy, A.name AS PharmacyName, B.Insurance_number,
B.name AS PharmacistName, B.surname AS PharmacistSurname
FROM PHARMACY A
LEFT JOIN PHARMACIST B
ON A.id_pharmacy = B.id_pharmacy
WHERE A.id_pharmacy IN (SELECT id_pharmacy FROM SELLS WHERE name = 'Kronol')