Creating views in SQL and receiving error - sql

I know that this is a simple fix, but I can't seem to figure out how to change the code so I don't get this error:
ORA-00918: column ambiguously defined
Here is the code:
CREATE VIEW BOOK_INVENTORY (BRANCH_NUM, UNITS) AS
SELECT BRANCH_NUM, ON_HAND
FROM BRANCH, INVENTORY
WHERE BRANCH.BRANCH_NUM = INVENTORY.BRANCH_NUM
GROUP BY BRANCH.BRANCH_NUM
ORDER BY BRANCH.BRANCH_NUM;
Thanks in advance for the help.

I'm guessing that you need to specify from which table you want BRANCH_NUM like:
CREATE VIEW BOOK_INVENTORY (BRANCH_NUM, UNITS) AS
SELECT BRANCH.BRANCH_NUM, ON_HAND
FROM BRANCH, INVENTORY
WHERE BRANCH.BRANCH_NUM = INVENTORY.BRANCH_NUM
GROUP BY BRANCH.BRANCH_NUM
ORDER BY BRANCH.BRANCH_NUM;
Also, you might want to consider using the post ANSI SQL-92 syntax for joins like so:
CREATE VIEW BOOK_INVENTORY (BRANCH_NUM, UNITS) AS
SELECT BRANCH.BRANCH_NUM, ON_HAND
FROM BRANCH
INNER JOIN INVENTORY ON BRANCH.BRANCH_NUM = INVENTORY.BRANCH_NUM
GROUP BY BRANCH.BRANCH_NUM
ORDER BY BRANCH.BRANCH_NUM;
See [Bad habits to kick : using old-style JOINs][1] for some reasoning about it.
[1]: https://sqlblog.org/2009/10/08/bad-habits-to-kick-using-old-style-joins

you are making SELECT BRANCH_NUM, ON_HAND without determine those columns from which tables. May be one of them exists in both tables, modify it for example to
SELECT INVENTORY.BRANCH_NUM, INVENTORY.ON_HAND
-- ...
of those columns from inside INVENTORY table).

CREATE VIEW BOOK_INVENTORY (BRANCH_NUM, UNITS) AS
SELECT BRANCH.BRANCH_NUM, INVENTORY.ON_HAND
FROM BRANCH, INVENTORY
WHERE BRANCH.BRANCH_NUM = INVENTORY.BRANCH_NUM
GROUP BY BRANCH.BRANCH_NUM, INVENTORY.ON_HAND
ORDER BY BRANCH.BRANCH_NUM;
PS this query does not make much sense - why are you grouping? Also you are joining two tables for no apparent reason. The only thing this does is exclude invalid BRANCH's

Related

I have to create a view with following attributes

Create a view named customer_mobile_details which has the following attributes. Display customer id,customer name,mobile number, sales id, net amount,model name and manufacturer name of the mobiles, they have purchased. Sort the records based on customer id,customer name,sales id in ascending order.enter image description here
My code is as below.
create view customer_mobile_details
as( select Customer_Info.Customer_ID, Customer_Info.Customer_Name,
Distributor.Mobilenumber,
Sales_Info.Salesid, Sales_Info.Net_Amount,
Mobile_Master.Model_Name, Mobile_Master.Manufacturer
from Customer_Info
inner join Sales_Info
on Customer_Info.Customer_ID = Sales_Info.Customer_ID
inner join Mobile_Master
on Sales_Info.Price = Mobile_Master.Price
inner join Distributor
on Mobile_Master.Distributor_ID = Distributor.Distributor_ID)
order by Customer_Info.Customer_ID, Customer_Info.Customer_Name, Sales_Info.Salesid asc;
But i'm getting some error. It says
Failed Test
Test Case 2: Check the attribute name,constraints,sorting etc.
Can someone help me to figure it out where I made the mistake?
You can try this one. Works for me.
This is pretty self explanatory.
create view customer_mobile_details as
(select customer_id,
customer_info.customer_name,
customer_info.mobile,
sales_info.salesid,
sales_info.net_amount,
mobile_master.model_name,
mobile_master.manufacturer
from customer_info
join sales_info using(customer_id)
join mobile_master using(ime_no))
order by customer_id,
customer_info.customer_name,
sales_info.salesid;
The issue is actually in the question as the mobile number to be taken is the attribute named "Mobile" from the table 'Customer_info' and not the "mobilenumber" attribute from table 'Distributor'.

SQL SELECT FOR SALES WITH 'COUNT' FROM ANOTHER TABLE

I have two tables. The first one is for sales (name's table is 'ventas') and the other one, for detailed articles by sale (the name is 'ventaArticulos'). Basically, the last one contains all the articles that were sold.
Those are related by the columns ventas.id_venta and ventaArticulos.id_ventaArticulo
Basically, the idea is to make an SQL SELECT for the first table (ventas) for example, getting the columns 'fecha' and 'importe' but also, perform a 'count' with the total of registers that are in the second table related by sale. (ventas.id_venta and ventaArticulos.id_ventaArticulo)
hope to be clear enough and can help me!
SQL to try to clarify (Obviously it doesn't work):
SELECT ventas.fecha, ventas.importe, count(ventaArticulos.id_codigoArt)
FROM ventas JOIN
ventaArticulos
ON ventaArticulos.id_ventaArticulo = ventas.id_venta
Thanks!
I would recommend to use table alise that could be easier to follow & you forgot to include GROUP BY Clause
SELECT v.fecha, v.importe, count(va.id_codigoArt) counts
FROM ventas v -- Use alise v entire the query instead of table_name
INNER JOIN ventaArticulos va ON va.id_ventaArticulo = v.id_venta
GROUP BY v.fecha, v.importe;
SELECT v1.fecha, v1.importe, count(v2.id_codigoArt)
FROM ventas v1 , ventaArticulos v2
where v1.id_ventaArticulo= v2.id_venta
group by v1.fecha, v1.importe
having count(*) > 1

How do I write an SQL query whose where clause is contained in another query?

I have two tables, one for Customer and one for Item.
In Customer, I have a column called "preference", which stores a list of hard criteria expressed as a WHERE clause in SQL e.g. "item.price<20 and item.category='household'".
I'd like a query that works like this:
SELECT * FROM item WHERE interpret('SELECT preference FROM customer WHERE id = 1')
Which gets translated to this:
SELECT * FROM item WHERE item.price < 20 and item.category = 'household'
Example data model:
CREATE TABLE customer (
cust_id INT
preference VARCHAR
);
CREATE TABLE item (
item_id INT
price DECIMAL(19,4)
category VARCHAR
);
# Additional columns omitted for brevity
I've looked up casting and dynamic SQL but I haven't been able to figure out how I should do this.
I'm using PostgreSQL 9.5.1
I'm going to assume that preference is the same as my made up item_id column. You may need to tweak it to fit your case. For future questions like this it may pay to give us the table structures you are working with, it really helps us out!
What you are asking for is a subquery:
select *
from item
where item_id in (select
preference
from
customer
where id = 1)
What I would suggest though is a join:
select item.*
from item
join customer on item.item_id = customer.preference
where item.price<20 and
item.category='household'
customer.id = 1
I decided to change my schema instead, as it was getting pretty messy to store the criteria in preferences in that manner.
I restricted the kinds of preferences that could be specified, then stored them as columns in Customer.
After that, all the queries I wanted could be expressed as joins.

Multi update query

I've created two temp tables. One with Orders which contains Article and Quantity and the other one with availability where we also have Article and Quantity. I would like to write a multi update query with subtracking order quantity from stock and from itself for all articles in temporary table with Orders. As far as I know it is not possible to alter two fields from different tables in one update query.
I've tried something like this, but it's of course doesn't work.
UPDATE #Stocks as s
INNER JOIN #Orders as o on o.ArticleId=s.ArticleId
SET
s.Quantity = (s.Quantity - o.Quanity)
FROM
#Stocks s
JOIN #Orders o on o.ArticleId=s.ArticleId
WHERE
#Stocks.ArticleId IN (SELECT ArticleId FROM #Orders)
When do you an update using a join with multiple matches, only one arbitrary row is chosen for the update. The key idea is to aggregate the data before the update:
UPDATE s
SET Quantity = (s.Quantity - o.Quanity)
FROM #Stocks s JOIN
(SELECT o.ArticleId, SUM(o.Quantity) as quantity
FROM #Orders o
GROUP BY o.ArticleId
) o
ON o.ArticleId = s.ArticleId;
Your statement is way over-complicated, mixing update syntax from SQL Server, MySQL, and Postgres. In addition, the WHERE clause is unnecessary because the JOIN does the filtering. However, even once the syntax errors are fixed, you will still have the problem of calculating incorrect results, unless you pre-aggregate the data.
Unfortunately, the description of this behavior is buried deep in the documentation of the first example on the update page:
The previous example assumes that only one sale is recorded for a
specified salesperson on a specific date and that updates are current.
If more than one sale for a specified salesperson can be recorded on
the same day, the example shown does not work correctly. The example
runs without error, but each SalesYTD value is updated with only one
sale, regardless of how many sales actually occurred on that day. This
is because a single UPDATE statement never updates the same row two
times. [emphasis added]
How about this?
UPDATE s
SET s.Quantity = (s.Quantity - o.Quanity)
FROM #Stocks as s
INNER JOIN #Orders as o on o.ArticleId=s.ArticleId
For updating two tables using single query, you should create a view that contain both tables columns and then update that view.
Your Question is all about Multi Update,
but updation perform in one table based on another table so
to do this use join
But if updation perform in two or more table we have to create view then we can update
thanks

SQL Counting and Joining

I'm taking a database course this semester, and we're learning SQL. I understand most simple queries, but I'm having some difficulty using the count aggregate function.
I'm supposed to relate an advertisement number to a property number to a branch number so that I can tally up the amount of advertisements by branch number and compute their cost. I set up what I think are two appropriate new views, but I'm clueless as to what to write for the select statement. Am I approaching this the correct way? I have a feeling I'm over complicating this bigtime...
with ad_prop(ad_no, property_no, overseen_by) as
(select a.ad_no, a.property_no, p.overseen_by
from advertisement as a, property as p
where a.property_no = p.property_no)
with prop_branch(property_no, overseen_by, allocated_to) as
(select p.property_no, p.overseen_by, s.allocated_to
from property as p, staff as s
where p.overseen_by = s.staff_no)
select distinct pb.allocated_to as branch_no, count( ??? ) * 100 as ad_cost
from prop_branch as pb, ad_prop as ap
where ap.property_no = pb.property_no
group by branch_no;
Any insight would be greatly appreciated!
You could simplify it like this:
advertisement
- ad_no
- property_no
property
- property_no
- overseen_by
staff
- staff_no
- allocated_to
SELECT s.allocated_to AS branch, COUNT(*) as num_ads, COUNT(*)*100 as ad_cost
FROM advertisement AS a
INNER JOIN property AS p ON a.property_no = p.property_no
INNER JOIN staff AS s ON p.overseen_by = s.staff_no
GROUP BY s.allocated_to;
Update: changed above to match your schema needs
You can condense your WITH clauses into a single statement. Then, the piece I think you are missing is that columns referenced in the column definition have to be aggregated if they aren't included in the GROUP BY clause. So you GROUP BY your distinct column then apply your aggregation and math in your column definitions.
SELECT
s.allocated_to AS branch_no
,COUNT(a.ad_no) AS ad_count
,(ad_count * 100) AS ad_cost
...
GROUP BY s.allocated_to
i can tell you that you are making it way too complicated. It should be a select statement with a couple of joins. You should re-read the chapter on joins or take a look at the following link
http://www.sql-tutorial.net/SQL-JOIN.asp
A join allows you to "combine" the data from two tables based on a common key between the two tables (you can chain more tables together with more joins). Once you have this "joined" table, you can pretend that it is really one table (aliases are used to indicate where that column came from). You understand how aggregates work on a single table right?
I'd prefer not to give you the answer so that you can actually learn :)