What is wrong with my join in this query? - sql

Im practicing basic SQL with this site http://www.sqlishard.com/Exercise
Here is the question:
S5.0 - INNER JOIN
Now that we can pull data out of a single table and qualify column
names, let's take it a step further. JOIN statements allow us to
'join' the rows of several tables together using a condition to define
how they match one another. SELECT [columns] FROM FirstTable INNER
JOIN SecondTable ON FirstTable.Id = SecondTable.FirstTableId
Try using the INNER JOIN syntax to SELECT all columns from the
Customers and Orders tables where the CustomerId column in Orders
matches the Id column in Customers. Since both tables have an Id
column, you will need to qualify the Customers id in the WHERE clause
with either the table name or a table alias.
Here is my answer:
SELECT *
FROM Customers AS c
INNER JOIN Orders AS o ON c.ID = o.ID
WHERE o.CustomerID = c.ID
The site says im wrong? Could anyone explain where i'm going wrong?
EDIT: I see now I dont need the WHERE clause, but the question states..
you will need to qualify the Customers id in the WHERE clause with
either the table name or a table alias.
Hence my confusion. Thanks none the less.

Try this way:
SELECT c.ID,o.ID
FROM Customers AS c
INNER JOIN Orders AS o ON o.CustomerID = c.ID
or using where clause
SELECT *
FROM Customers AS c, Orders AS o
where o.CustomerID = c.ID

If you use JOIN.. ON, you do not need where clause

Related

oracle sql statement help to query against multiple tables

I am struggling with a sql statement. I am hoping a guru can help a beginner out, currently I have multiple select in statements.. but think there is a better way as I have been stuck.
Below are the tables and pertinent columns in each table
country
-country_id
barcodes_banned_in_country
-barcode(varchar)
-country_id
-country_name
orders
-order_id
-country_name
item
-order_id
-item_id
-barcode(varchar)
The goal is to get all orders that are banned based off the barcode banned list.
Any help with this sql statement would be appreciated.
One option uses exists:
select o.*
from orders o
where exists (
select 1
from barcodes_banned_in_country bic
inner join item i on i.barcode = bic.barcode
where i.order_id = o.order_id and bic.country_name = o.country_name
)
This brings all orders whose at least one item have a barcode that is banned in the order's country.
If, on the other hand, you want the list of the banned barcodes per order, then you can join and aggregate:
select o.order_id, o.country_name, listagg(i.barcode, ',') banned_barcodes
from orders o
inner join item i
on i.order_id = o.order_id
inner join barcodes_banned_in_country bic
on i.barcode = bic.barcode
and bic.country_name = o.country_name
group by o.order_id, o.country_name
Note that, as commented by MT0, you should really be storing the id of the country in orders rather than the country name. Accordingly, you wouldn't need the country name in the banned barcodes table.

Query with columns from 4 tables in SQL

Can anyone who knows SQL, specifically the flavor used in Microsoft Access 2013, tell me what I'm doing wrong here?
SELECT custid, custname, ordno, itemno, itemname
FROM cust
INNER JOIN order
ON cust.custid = order.custid
INNER JOIN orderitems
ON order.ordno = orderitems.ordno
INNER JOIN inv
ON orderitems.itemno = inv.itemno;
I've already read other, similar questions, and tried the methods they used in their solutions, but I'm getting a "Syntax error in FROM clause.", almost no matter what I try.
* * *
SOLUTION: Thanks for the replies! In addition to adding square brackets around "order" and using TableName.ColumnName syntax in SELECT, I had to use parentheses for my multiple INNER JOINs. Here is the fixed code:
SELECT cust.custid, cust.custname, [order].ordno, orderitems.itemno, inv.itemname
FROM ((cust
INNER JOIN [order]
ON cust.custid = [order].custid)
INNER JOIN orderitems
ON [order].ordno = orderitems.ordno)
INNER JOIN inv
ON orderitems.itemno = inv.itemno;
SELECT cust.custid --<-- Use two part name here
,cust.custname
,[order].ordno
,orderitems.itemno --<-- Only guessing here use the correct table name
,inv.itemname --<-- Only guessing here use the correct table name
FROM cust
INNER JOIN [order]
ON cust.custid = [order].custid --<-- used square brackets [] around ORDER as it is
INNER JOIN orderitems -- a key word.
ON [order].ordno = orderitems.ordno
INNER JOIN inv
ON orderitems.itemno = inv.itemno;
In your Select Statament you need to use Two Part name i.e TableName.ColumnName since these column can exist in more than one Tables in your FROM clause you need to tell sql server that columns in your select coming from which table in your from clause.

SQL the column exists more than once

This is working fine
SELECT i.*,o.*,p.*
FROM orders o
INNER JOIN oitems i
ON i.orderid = o.orderid
LEFT OUTER JOIN products p
ON i.catalogid = p.catalogid
however i want to perform a nested select as an example this is giving the coulmn x exists more than once
SELECT AA.*,
FROM (
SELECT i.*,o.*,p.*
FROM orders o
INNER JOIN oitems i
ON i.orderid = o.orderid
LEFT OUTER JOIN products p
ON i.catalogid = p.catalogid ) AA
i know the second example makes no sense , but i need another select with groupping, is there a way to fix the coulm exists more than once error without having to specify the column names in the select statement?
By using *, you are getting the same column more than once in your output. To avoid, this, specifically state the columns you want returned, instead.
The culprits are likely orderid and catalogid which both exist in more than one table, but there may be others.
You have mention column names specifically. I can see that you are using "*". you have to use like select i.columnName,o.columnName etc

Selecting Data from 2 tables based on another

I am using Oracle via the SQL+ command line, i'm trying to display data from two different tables, but i require the use of a third table to determine what to display. Below is an image of my sample 3 tables.
Stack won't let me show my images in the question so here is a link:
I want to display the "Name","O_ID" and "Date" for each order. I'm quite new to SQL and this may have been answered before but i could not find it.
JOIN the tables:
SELECT
c.Name,
o.O_ID,
od.Date
FROM Customer AS c
INNER JOIN "Order" AS o ON c.C_ID = o.C_ID
INNER JOIN OrderDate AS od ON o.O_ID = od.O_ID;
What you are attempting to do is a very common practice and requires a INNER JOIN.
From a design perspective, the Order Date table shouldn't even exist. The date column should just reside within the Order table. I wrote the query based on that design:
SELECT
o.O_ID,
o.Date,
c.Name,
FROM
customer AS c
INNER JOIN order AS o ON c.C_ID = o.C_ID
Edit:
More on the issue of your design: A natural ordering of your data would be that there is 1 date for an order, not many dates for an order. Introducing another table to simply store the date allows for there to potentially be many dates associated with an order, which is simply unnatural.
Do a JOIN
select c.Name, o.O_ID, od.Date
from Customer c
inner join Order o on o.O_ID = c.C_ID
inner join OrderDate od on o.O_ID = od_ID
Doc: http://www.w3schools.com/sql/sql_join.asp

Find records that do not have related records in SQL

I have 2 tables (Orders, OrderItems) that are related based on a column OrderID. I need to find all Orders that do not have any OrderItems.
We use JOIN to find related data. To find data without any related data, we can use an anti-join.
The following joins the tables, then selects those without any order items. This tends to be more efficient that a WHERE id NOT IN (...) style query.
select *
from
Orders O
left outer join OrderItems I
on I.OrderId = O.Id
where
I.Id is null
Select * From Orders Where OrderID not in (Select Distinct OrderID From OrderItems)
try with LEFT EXCEPTION JOIN
select *
from Orders
LEFT EXCEPTION JOIN OrderItems ON ...