Re: Relation subset operators
Date: Wed, 3 Jun 2009 07:23:19 -0700 (PDT)
Message-ID: <902889ae-7034-4a6a-a619-a911feb0957a_at_o20g2000vbh.googlegroups.com>
>> Comments would be welcome to evaluate the usefulness of such an operator. <<
Just for comparison, I re-wrote the skeleton schema in SQL and brought
the data element names up to ISO-11179 standards. The dates also need
to be in ISO-8601 format, but that is not important for this
comparison.
CREATE TABLE CarSales
> Question 1: What are the total sales of salesmen who have sold AT LEAST (one) Blue vehicle.
SELECT C1.salesman_name, SUM(C1.vehicle_price) AS sales_tot
FROM CarSales AS C1
> Question 2: What are the total sales of salesmen who have sold AT LEAST (one) blue vehicle AND (one) red vehicle.
SELECT C1.salesman_name, SUM(C1.vehicle_price) AS sales_tot
FROM CarSales AS C1
> Question 3: What are the total sales of salesmen who have sold AT LEAST (one) blue vehicle OR (one) red vehicle.
SELECT C1.salesman_name, SUM(C1.vehicle_price) AS sales_tot
FROM CarSales AS C1
> Question 4: What are the total sales of salesmen who have NOT sold ANY blue vehicles
SELECT C1.salesman_name, SUM(C1.vehicle_price) AS sales_tot
(invoice_nbr INTEGER NOT NULL PRIMARY KEY,
vehicle_make VARCHAR(10) NOT NULL,
salesman_name VARCHAR(10) NOT NULL,
vehicle_price DECIMAL (8,2) NOT NULL,
vehicle_color VARCHAR(10) NOT NULL,
sale_date DATE DEFAULT CURRENT_TIMESTAMP NOT NULL);
WHERE C1.salesman_name
IN (SELECT C2.salesman_name
FROM CarSales AS C2
WHERE C2.vehicle_color = 'Blue') ;
WHERE C1.salesman_name
IN (SELECT C2.salesman_name
FROM CarSales AS C2
WHERE C2.vehicle_color IN ( 'Blue', 'Red')
GROUP BY C2.salesman_name
HAVING COUNT(DISTINCT C2.vehicle_color) = 2);
WHERE C1.salesman_name
IN (SELECT C2.salesman_name
FROM CarSales AS C2
WHERE C2.vehicle_color IN ( 'Blue', 'Red')
GROUP BY C2.salesman_name
HAVING COUNT(DISTINCT C2.vehicle_color) > 0);
WHERE C1.salesman_name
NOT IN (SELECT C2.salesman_name
FROM CarSales AS C2
WHERE C2.vehicle_color = 'Blue');
> Question 5: What are the total sales of salesmen who have NOT sold NEITHER a blue vehicle NOR a red vehicle
SELECT C1.salesman_name, SUM(C1.vehicle_price) AS sales_tot
FROM CarSales AS C1
WHERE C1.salesman_name
NOT IN (SELECT C2.salesman_name
FROM CarSales AS C2
WHERE C2.vehicle_color IN ( 'Blue', 'Red')
GROUP BY C2.salesman_name
HAVING COUNT(DISTINCT C2.vehicle_color) > 0);
I did not test these queries and I used the IN() predicate rather than EXISTS() to keep them closer to relational algebra and set notation.
However, if the specs are changed a bit to show a zero total for the disqualified salesmen, the queries could have been written with a CASE expressions: Here is Q1:
SELECT C1.salesman_name,
SUM( CASE WHEN C1.vehicle_color = 'Blue' THEN C1.vehicle_price ELSE 0.00 END) AS blue_sales_tot
FROM CarSales AS C1
GROUP BY C1.salesman_name;
This is very simple SQL and you could nest it inside another query to meet the original specs:
SELECT salesman_name, blue_sales_tot
FROM ( SELECT C1.salesman_name,
SUM( CASE WHEN C1.vehicle_color = 'Blue' THEN C1.vehicle_price ELSE 0.00 END) AS blue_sales_tot
FROM CarSales AS C1
GROUP BY C1.salesman_name) AS B(salesman_name, blue_sales_tot) WHERE blue_sales_tot > 0; Received on Wed Jun 03 2009 - 16:23:19 CEST