Find all rented cards using EXCEPT or NOT EXISTS - sql

My Database is like this
CUSTOMER (NAME,VAT,PHONE)
CAR(PLATENR,COLOUR)
RENTS(VAT,PLATENR, RENTDATE)
What I want to find is all the black cars that were rented by all customers (all VAT Numbers).
I want to use nested subqueries and EXCEPT or NOT EXISTS.
I already have this query using COUNT that works.
SELECT rents.PlateNr
FROM Rents,Car
WHERE Car.colour='black' AND car.PlateNr=rents.PlateNr
GROUP BY rents.PlateNr
HAVING COUNT(DISTINCT VAT) = (SELECT COUNT(*) FROM Customer);
I am trying to use this guide http://www.inf.usi.ch/faculty/soule/teaching/2016-fall/db/division.pdf to get my result but I don't get how the query is implemented in my case.

I was looking an answer similar to the link that I provided above regarding division.
After some search and try the final division query using except is this:
SELECT PlateNr
FROM Car
WHERE colour='black'
EXCEPT
SELECT PlateNr
FROM (SELECT car.PlateNr, rents.VAT
FROM car,rents
EXCEPT
SELECT PlateNr,VAT
FROM rents)
Have tried it in POSTGRE that supports EXCEPT and everything works like a charm.

Related

Aggregate function returning different result compared to the algebraic expression of rows

I´ve recently started with SQL and would like to know the following:
I have a problem I´m trying to solve, and both my solution and the official resolution are very similar, yet return very different results, the problem consists of a table with the following values
:
I am supposed to "find the total domestic and international sales that can be attributed to each director"
Here is what I wrote :
SELECT Director,(Domestic_sales + International_sales) AS Total_sales From Movies
INNER JOIN Boxoffice
ON Movies.Id=Boxoffice.Movie_Id
GROUP BY Director
And here is the official solution:
SELECT director, SUM(domestic_sales + international_sales) as Cumulative_sales_from_all_movies
FROM movies
INNER JOIN boxoffice
ON movies.id = boxoffice.movie_id
GROUP BY director;
I understand that the SUM aggregated function will do the trick, but why does simply adding up the values as I did return a different value? Issit because it's not taking into consideration the different films, but just adding up one of the lists in the movie and throwing that result?
I´ve looked elsewhere and also checked other questions seeing if I could answer this, but to no avail.
Thanks everyone and have a great week!
why does simply adding up the values as I did return a different value? Issit because it's not taking into consideration the different films, but just adding up one of the lists in the movie and throwing that result?
Your query is not standard SQL. In fact, this will return an error in almost all databases, including the most recent versions of MySQL, because you are aggregating by one column but have other non-aggregated columns in the SELECT:
SELECT m.Director, (bo.Domestic_sales + bo.International_sales) AS Total_sales
FROM Movies m JOIN
Boxoffice bo
ON M.Id = bo.Movie_Id
GROUP BY m.Director;
(I added table aliases, which are highly recommended.)
In older versions of MySQL, this returns an arbitrary value for the sum -- from one matching row. The equivalent in more recent versions uses ANY_VALUE():
SELECT m.Director, ANY_VALUE(bo.Domestic_sales + bo.International_sales) AS Total_sales
FROM Movies m JOIN
Boxoffice bo
ON M.Id = bo.Movie_Id
GROUP BY m.Director;
Obviously, an arbitrary value is different from a SUM().
I would advise you to set the session to avoid this problem. You can set ONLY_FULL_GROUP_BY to get the standard and compatible behavior.

Repeat a query over the parameter list

I would like to iterate the same query while using different parameter values from a predefined list.
Say, I have a table with two columns. The first columns contains customer name. The second column contains customer spending.
###CUSTOMER; SPENDING###
customer1; 1000
customer2; 111
customer3; 100
customer1; 323
...
I know the complete list of customers: customerlist = {customer1, customer2, customer3}.
I would like to do something like:
Select sum(spending)
from mytable
where customer = #customerlist
The query should compute the sum of spending for each customer defined in the customer list. I have found some examples of sql procedures with stored parameters but not the case with one parameter of multiple values.
Thank you
P.S. This is just a hypothetical example to illustrate my question (I know it would be much more effective to use here a simple group by).
You can use nested query like this
SELECT CustomerList.CustomerName Cust, isnull((SELECT SUM(Spending) CustSpending
FROM Customer
WHERE Customer.CustomerName = CustomerList.CustomerName),0)
FROM CustomerList
This would normally be done using GROUP BY:
Select customer, sum(spending)
from mytable
group by customer;
GROUP BY is a very fundamental part of SQL. You should review your knowledge of SQL so you understand how to use it.

(SQL) Using SELECT statements to display data with odd requirements

So I'm taking a course on learning basic SQL (using Oracle), and I felt like I had become fairly fluent with using SELECT statements (grouping, joining, having, etc), but now I'm at a loss on how to deal with this latest problem.
I need to write a statement that would only display rows with more than one piece of data. So, say I had
COMPANY PRODUCT
One Car
One Book
Two Game
it should only list company 'One'. But I can't find anything online to help me.
Select Company
From YourTableName
Group By Company
Having Count(*) > 1
better way to know count of each company is :
Select Company,Count(*)
From Table
Group By Company
Having Count(*) > 1

Complex sql select

I can't figure out how to make this sql select statement...Here are my tables :
I opened the tables concerned by the request
So basically I want to select the number of albums for each interpret.
I just can't figure it out... I am currently thinking that I need to do my first select on album like :
select interpret.no_interpret, count(*)
from album
.
.
.
group by interpret.no_interpret;
and there work from this but I don't know where to go next.
I may be missing something, but I'm not seeing the direct relation from your song table to the album...
I would first start by getting the link_interpret_song table joined to the song table and get count of distinct albums. However, I didn't see what appears to be a "No_Album" column in the field list of the song table. I can only guess it IS in there associated to the particular album. I did see media, but to me, that would be like a TYPE of media (digital, download, vinyl, CD) vs the actual ID Key apparent to the album table.
That said, I am thinking there IS such a "No_Album" column in the SONG table.
select
LIS.No_Interpret,
COUNT( DISTINCT S.No_Album )
from
Link_Interpret_Song LIS
JOIN Song S
on LIS.No_Song = S.No_Song
group by
LIS.No_Interpret;
Now, that said, if you want the interpret details, take the above results and join that to the interpret table. I've done both distinct album count and total # of songs just as an example of count() vs count(distinct) context... such as
select
PreCounts.No_Interpret,
PreCounts.DistinctAlbums,
PreCounts.ActualSongs,
I.Name_Interpret,
I.First_Name,
I.Stage_Name
from
( select
LIS.No_Interpret,
COUNT( DISTINCT S.No_Album ) as DistinctAlbums,
COUNT(*) as ActualSongs
from
Link_Interpret_Song LIS
JOIN Song S
on LIS.No_Song = S.No_Song
group by
LIS.No_Interpret ) as PreCounts
JOIN Interpret I
ON PreCounts.No_Interpret = I.No_Interpret
The question is ambiguous since there isn't a clear indication of how the tables are related. Given assumptions about these relations, your query will likely take on something similar to the following form:
SELECT COUNT(distinct a.no_album) from album a, interpret i, song s
where i.no_song=s.no_song
and a.no_album=s.no_album GROUP BY i.no_interpret

Select columns with the same value

I'm trying to select customer names with the same zip code but I can't seem to get the correct result. The correct rows that are meant to be returned are 11. I seem to be getting 14 using the following:
SELECT a.customer_first_name, a.customer_last_name, a.customer_zip FROM customers a
UNION
SELECT b.customer_first_name, b.customer_last_name, b.customer_zip FROM customers b
From here I'm kinda stuck. I know that both statements are the same but this is the basis of where I got to.
I was going to use something along the lines of:
WHERE a.customer_zip=b.customer_zip
But of course this doesn't work and is kind of irrelevant.
Customers table:
Any help would be much appreciated. If I've missed anything and/or this comes across unclear, then I apologise. Thanks.
Edit: The correct result should be 11 rows (which I can't seem to achieve).
I would do:
select customer_zip
from customers
group by customer_zip
having count(customer_zip)>1
edit:
this will give a list of duplicate ZIPs. based on it, you can esily find the customers with those zips with a select * from customers where customer_zip in (previous_query)
SELECT customer_first_name, customer_last_name, customer_zip
FROM customers where customer_zip in
(SELECT customer_zip FROM customers
GROUP BY customer_zip
HAVING COUNT(*) > 1);