What's wrong with this SQL CREATE + INSERT batch? - sql

What is wrong with this SQL statement?
Create table JaretsSchedule
(
ScheduleID Int Primary Key NOT NULL,
FieldID Int NOT NULL,
HomeTeamID Int NOT NULL,
AwayTeamID Int NOT NULL,
GameTime DateTime NOT NULL
);
Insert into JaretsSchedule
Values
(1, 1, 1, 2, '2012-10-02 12:00:00'),
(1, 1, 1, 3, '2012-10-17 12:00:00'),
(1, 1, 1, 4, '2012-09-23 12:00:00'),
(1, 2, 2, 1, '2012-09-12 12:00:00'),
(1, 3, 3, 1, '2012-08-19 12:00:00'),
(1, 4, 4, 1, '2012-07-25 12:00:00'),
(2, 2, 2, 1, '2012-09-15 12:00:00'),
(2, 2, 2, 3, '2012-09-06 12:00:00'),
(2, 2, 2, 4, '2012-08-28 12:00:00'),
(2, 1, 1, 2, '2012-10-02 12:00:00'),
(2, 3, 3, 2, '2012-08-11 12:00:00'),
(2, 4, 4, 2, '2012-07-17 12:00:00'),
(3, 3, 3, 1, '2012-08-19 12:00:00'),
(3, 3, 3, 2, '2012-08-11 12:00:00'),
(3, 3, 3, 4, '2012-08-03 12:00:00'),
(3, 1, 1, 3, '2012-10-17 12:00:00'),
(3, 2, 2, 3, '2012-10-17 12:00:00'),
(3, 4, 4, 3, '2012-07-09 12:00:00'),
(4, 4, 4, 1, '2012-07-25 12:00:00'),
(4, 4, 4, 2, '2012-07-17 12:00:00'),
(4, 4, 4, 3, '2012-07-09 12:00:00'),
(4, 1, 1, 4, '2012-09-23 12:00:00'),
(4, 2, 2, 4, '2012-08-28 12:00:00'),
(4, 3, 3, 4, '2012-08-03 12:00:00');
With the resulting error:
Msg 2627, Level 14, State 1, Line 8
Violation of PRIMARY KEY constraint 'PK__JaretsSc__9C8A5B696CFE9A03'. Cannot insert duplicate key in object 'dbo.JaretsSchedule'. The duplicate key value is (1).

The error message is literally telling you what the problem is. You can't insert the same value more than once for the ScheduleID column, which you have defined as the primary key. Once workaround here would be to just make this column an identity/auto increment column. Then, don't even include a value for it when inserting. Instead, let SQL Server handle it:
CREATE TABLE JaretsSchedule (
ScheduleID INT NOT NULL IDENTITY PRIMARY KEY,
FieldID INT NOT NULL,
HomeTeamID INT NOT NULL,
AwayTeamID INT NOT NULL,
GameTime DateTime NOT NULL
);
INSERT INTO JaretsSchedule (FieldID, HomeTeamID, AwayTeamID, GameTime)
VALUES
(1, 1, 2, '2012-10-02 12:00:00'),
(1, 1, 3, '2012-10-17 12:00:00'),
(1, 1, 4, '2012-09-23 12:00:00'),
...
Note also that I explicitly list out the columns, in order, which are the target for the insert. This is also best practice, and avoids a situation later on wher it might not be clear to which columns the data in the VALUES clause corresponds.

Related

Starting and Ending a row-count based on values in another column

There is a need to monitor the performance of a warehouse of goods. Please refer to the table containing data for one warehouse below:
WK_NO: Week number; Problem: Problem faced on that particular week. Empty cells are NULLs.
I need to create the 3rd column:
Weeks on list: A column indicating the number of weeks that a particular warehouse is being monitored as of that particular week.
Required Logic:
Initially the column's values are to be 0. If a warehouse is encountering problems continuously for 4 weeks, it is put onto a "list" and a counter starts, indicating the number of weeks the warehouse has been problematic. And if the warehouse is problem-free for 4 continuous weeks after facing problems, the counter resets to 0 and stays 0 until there is another 4 weeks of problems.
Code to generate data shown above:
CREATE TABLE warehouse (
WK_NO INT NOT NULL,
Problem STRING,
Weeks_on_list_ref INT
);
INSERT INTO warehouse
(WK_NO, Problem, Weeks_on_list_ref)
VALUES
(1, NULL, 0),
(2, NULL, 0),
(3, 'supply', 0),
(4, 'supply', 0),
(5, 'manpower', 0),
(6, 'supply', 0),
(7, 'manpower', 1),
(8, 'supply', 2),
(9, NULL, 3),
(10, NULL, 4),
(11, 'supply', 5),
(12, 'supply', 6),
(13, 'manpower', 7),
(14, NULL, 8),
(15, NULL, 9),
(16, NULL, 10),
(17, NULL, 11),
(18, NULL, 0),
(19, NULL, 0),
(20, NULL, 0);
Any help is much appreciated.
Update:
Some solutions are failing when bringing in data for multiple warehouses.
Updated the code generation script with W_NO which is the warehouse ID, for your consideration.
CREATE OR REPLACE TABLE warehouse (
W_NO INT NOT NULL,
WK_NO INT NOT NULL,
Problem STRING,
Weeks_on_list_ref INT
);
INSERT INTO warehouse
(W_NO, WK_NO, Problem, Weeks_on_list_ref)
VALUES
(1, 1, NULL, 0),
(1, 2, NULL, 0),
(1, 3, 'supply', 0),
(1, 4, 'supply', 0),
(1, 5, 'manpower', 0),
(1, 6, 'supply', 0),
(1, 7, 'manpower', 1),
(1, 8, 'supply', 2),
(1, 9, NULL, 3),
(1, 10, NULL, 4),
(1, 11, 'supply', 5),
(1, 12, 'supply', 6),
(1, 13, 'manpower', 7),
(1, 14, NULL, 8),
(1, 15, NULL, 9),
(1, 16, NULL, 10),
(1, 17, NULL, 11),
(1, 18, NULL, 0),
(1, 19, NULL, 0),
(1, 20, NULL, 0),
(2, 1, NULL, 0),
(2, 2, NULL, 0),
(2, 3, 'supply', 0),
(2, 4, 'supply', 0),
(2, 5, 'manpower', 0),
(2, 6, 'supply', 0),
(2, 7, 'manpower', 1),
(2, 8, 'supply', 2),
(2, 9, NULL, 3),
(2, 10, NULL, 4),
(2, 11, 'supply', 5),
(2, 12, 'supply', 6),
(2, 13, 'manpower', 7),
(2, 14, NULL, 8),
(2, 15, NULL, 9),
(2, 16, NULL, 10),
(2, 17, NULL, 11),
(2, 18, NULL, 0),
(2, 19, NULL, 0),
(2, 20, NULL, 0);
Consider below query for updated question:
SELECT W_NO, WK_NO, Problem, IF(MOD(div, 2) = 0, 0, RANK() OVER (PARTITION BY W_NO, div ORDER BY WK_NO)) AS Weeks_on_list
FROM (
SELECT *, COUNTIF(flag IS TRUE) OVER (PARTITION BY W_NO ORDER BY WK_NO) AS div FROM (
SELECT *,
LAG(Problem, 5) OVER w0 IS NULL AND COUNT(Problem) OVER w1 = 4 OR
LAG(Problem, 5) OVER w0 IS NOT NULL AND COUNT(Problem) OVER w1 = 0 AS flag
FROM warehouse
WINDOW w0 AS (PARTITION BY W_NO ORDER BY WK_NO), w1 AS (w0 ROWS BETWEEN 4 PRECEDING AND 1 PRECEDING)
)
)
ORDER BY W_NO, WK_NO;
Consider below query:
Using a window frame with fixed size 4, find boundaries first where
warehouse turns into abnormal state and vice versa in innermost query.
Partition weeks using boundaries found in step 1.
Since normal and abnormal states take turns, so calculate RANK() only for abnormal state in outermost query.
SELECT WK_NO, Problem, IF(MOD(div, 2) = 0, 0, RANK() OVER (PARTITION BY div ORDER BY WK_NO)) AS Weeks_on_list
FROM (
SELECT *, COUNTIF(flag IS TRUE) OVER (ORDER BY WK_NO) AS div FROM (
SELECT *,
LAG(Problem, 5) OVER w0 IS NULL AND COUNT(Problem) OVER w1 = 4 OR
LAG(Problem, 5) OVER w0 IS NOT NULL AND COUNT(Problem) OVER w1 = 0 AS flag
FROM warehouse
WINDOW w0 AS (ORDER BY WK_NO), w1 AS (w0 ROWS BETWEEN 4 PRECEDING AND 1 PRECEDING)
)
)
ORDER BY WK_NO;

Insert statement conflicted with foreign key

I'm new to SQL and I'm trying to insert values into my table. I'm currently using SQL Server Management Studio.
CREATE TABLE Materials
(
materials_ID int NOT NULL PRIMARY KEY,
floor_boards int NOT NULL,
power_Points int NOT NULL,
electrical_Wiring int NOT NULL,
stairs_Pack int NOT NULL,
);
SELECT * FROM materials;
-- Creation of the JobCards Table
CREATE TABLE jobCards
(
customer_id VARCHAR(50)
FOREIGN KEY REFERENCES Customers(customer_id),
jobCardID int NOT NULL PRIMARY KEY,
materials_ID int
FOREIGN KEY REFERENCES Materials(materials_ID),
jobType VARCHAR(150) NOT NULL,
rate decimal NOT NULL,
no_of_days int NOT NULL,
city VARCHAR(150) NOT NULL,
);
-- Selectin statement output values in Jobcards
SELECT * FROM jobCards;
-- Insert statement allows data to be inputed to table
INSERT INTO jobCards (customer_id, jobCardID, materials_ID, jobType, rate, no_of_days, city)
VALUES
('0001', 11000, 1, 'Full Conversion', 120000, 7, 'Pretoria'),
('0002', 10478, 2, 'Semi Conversion', 1080, 2, 'Pretoria'),
('0003', 14253, 3, 'Floor Boarding', 900, 2, 'Pretoria'),
('0004', 11258, 4, 'Full Conversion', 120000, 8, 'Pretoria'),
('0005', 12058, 5, 'Semi Conversion', 1080, 3, 'Pretoria'),
('0006', 13697, 6, 'Full Conversion', 120000, 7, 'Pretoria'),
('0007', 10211, 7, 'Full Conversion', 120000, 7, 'Pretoria'),
('0008', 10471, 8, 'Semi Conversion', 1080, 2, 'Pretoria'),
('0009', 13521, 9, 'Semi Conversion', 1080, 3, 'Pretoria'),
('0010', 10102, 10, 'Floor Boarding', 900, 2, 'Pretoria');
I have inserted the tables that have the issue. Whenever I run my program I get this error
The INSERT statement conflicted with the FOREIGN KEY constraint
"FK__jobCards__materi__2F10007B". The conflict occurred in database
"DomingoRoofWorks", table "dbo.Materials", column 'materials_ID'.
Remember that a foreign key is a field that help us to link two tables together. We can use a foreign key to refer to the primary key in another table.
You can try to insert some rows in the Materials table before inserting into the jobCards table.
Here is an example:
-- After creating the tables:
INSERT INTO Materials (materials_ID, floor_boards, power_Points, electrical_Wiring, stairs_Pack)
VALUES (1, --someIntValue, --someIntValue, --someIntValue, --someIntValue)
After inserting all the rows needed you can use those Ids as a foreign key in the jobCards table. At this point, this query could be performed wothout problem.
INSERT INTO jobCards (customer_id, jobCardID, materials_ID, jobType, rate, no_of_days, city)
VALUES
('0001', 11000, 1, 'Full Conversion', 120000, 7, 'Pretoria'),
('0002', 10478, 2, 'Semi Conversion', 1080, 2, 'Pretoria'),
('0003', 14253, 3, 'Floor Boarding', 900, 2, 'Pretoria'),
('0004', 11258, 4, 'Full Conversion', 120000, 8, 'Pretoria'),
('0005', 12058, 5, 'Semi Conversion', 1080, 3, 'Pretoria'),
('0006', 13697, 6, 'Full Conversion', 120000, 7, 'Pretoria'),
('0007', 10211, 7, 'Full Conversion', 120000, 7, 'Pretoria'),
('0008', 10471, 8, 'Semi Conversion', 1080, 2, 'Pretoria'),
('0009', 13521, 9, 'Semi Conversion', 1080, 3, 'Pretoria'),
('0010', 10102, 10, 'Floor Boarding', 900, 2, 'Pretoria');

Sum over range but reset when other column value is 1

So I have an account number and a reading number that I want to take the cumulative sum of but reset at the beginning of a new reading cycle (I want to reset the running sum).
I am using a window function but cannot figure out how to set it when the new reading cycle exists.
Data has the following format:
The Reading cycle Volume value is what I am attempting to achieve.
Currently I have tried SUM(Value) OVER(PARTITION BY ACCOUNT ORDER BY OBS)
I do not know how to reset it when reading # = 1.
I have tried:
Case
when [Reading #] = 1 THEN value
ELSE SUM(Value) OVER(PARTITION BY ACCOUNT ORDER BY OBS)
END AS [Running Total]
If I understand the question correctly and the values, stored in the Obs and [Reading #] columns are without gaps, the next approach is an option:
Table:
SELECT *
INTO Data
FROM (VALUES
(1, 1, 1, 5),
(1, 2, 2, 6),
(1, 3, 3, 5),
(1, 4, 4, 6),
(1, 5, 5, 5),
(1, 6, 6, 5),
(1, 7, 1, 5),
(1, 8, 2, 6),
(1, 9, 3, 5),
(1, 10, 4, 6),
(1, 11, 5, 5),
(1, 12, 6, 5),
(2, 1, 1, 7),
(2, 2, 2, 8),
(2, 3, 3, 9),
(2, 4, 4, 10),
(2, 5, 5, 11),
(2, 6, 6, 12),
(2, 7, 1, 7),
(2, 8, 2, 8),
(2, 9, 3, 9),
(2, 10, 4, 10),
(2, 11, 5, 11),
(2, 12, 6, 12)
) v (Account, Obs, [Reading #], [Value])
Statement:
SELECT
Account, Obs, [Reading #], [Value],
SUM([Value]) OVER (PARTITION BY Account, [Group] ORDER BY Account, Obs) AS [Ready Cicle Value]
FROM (
SELECT
*,
(Obs - [Reading #]) AS [Group]
FROM Data
) t
One additional option (as a more general approach) is to create groups when [Reading #] is equal to 1:
SELECT
Account, Obs, [Reading #], [Value],
SUM([Value]) OVER (PARTITION BY Account, [Group] ORDER BY Obs) AS [Ready Cicle Value]
FROM (
SELECT *, SUM([Change]) OVER (PARTITION BY Account ORDER BY Obs) AS [Group]
FROM (
SELECT *, CASE WHEN [Reading #] = 1 THEN 1 ELSE 0 END AS [Change]
FROM Data
) a
) b
Help us to help you. Always include a minimal set of data and the code we need, which we can copy and paste to immediately be on the same page as you without wasting time & effort that is better spent helping others. Note how you can simply copy and paste our solutions and play with them? They are complete and stand alone. That is what we are looking for from you.
You are close. The piece you are missing is that you need some way to group your readings and then you can include that in your partitioning as well.
There are any number of ways to create the new derived value for "reading_group" the following is just one way.
DECLARE #t_customer_readings TABLE
( account_number INT,
observation INT,
reading_number INT,
reading_value INT
)
INSERT INTO #t_customer_readings
VALUES (1, 1 , 1, 3),
(1, 2 , 2, 6),
(1, 3 , 3, 9),
(1, 4 , 4, 5),
(1, 5 , 5, 5),
(1, 6 , 6, 8),
(1, 7 , 1, 1),
(1, 8 , 2, 4),
(1, 9 , 3, 7),
(1, 10, 4, 0),
(1, 11, 5, 3),
(1, 12, 6, 6),
(2, 1 , 1, 9),
(2, 2 , 2, 2),
(2, 3 , 3, 5),
(2, 4 , 4, 8),
(2, 5 , 5, 1),
(2, 6 , 6, 4),
(2, 7 , 1, 7),
(2, 8 , 2, 0),
(2, 9 , 3, 3),
(2, 10, 1, 6), -- note I have split this group into 2 to show that the reading numbers do not need to be sequential.
(2, 11, 5, 9),
(2, 12, 6, 2)
SELECT r.*,
-- reading_group = CASE WHEN r.reading_number = 1 THEN observation ELSE rg.reading_group END,
ready_cycle_volume = SUM(reading_value) OVER(PARTITION BY account_number,
CASE WHEN r.reading_number = 1 THEN observation
ELSE rg.reading_group
END
ORDER BY observation)
FROM #t_customer_readings r
CROSS APPLY
(SELECT reading_group = MAX(observation) -- I picked observation but you could use whatever value you like. we are just creating something we can group on.
FROM #t_customer_readings
WHERE account_number = r.account_number
AND observation < r.observation
AND reading_number = 1) rg

SQL request error

Good evening everyone,
I'm working on a assignment and can't figure out the following, I have two tables:
CREATE TABLE Rental (
rental_id DECIMAL(12) PRIMARY KEY,
customer_id DECIMAL(12),
movie_id DECIMAL(12),
delivery_status VARCHAR(64),
return_status VARCHAR(64));
and
CREATE TABLE Movie (
movie_id DECIMAL(12) PRIMARY KEY,
DVD_id INTEGER NOT NULL,
title VARCHAR(64) NOT NULL,
stock_number DECIMAL(12),
director_id DECIMAL(12),
genre_id DECIMAL(12),
release_date DATE NOT NULL,
restrictions VARCHAR(256) NOT NULL);
I need to do the following, list the names of all movies that are currently unavailable, rented and not yet returned. And this is my query:
SELECT Movie.movie_id, Movie.title, Movie.stock_number
FROM Movie
WHERE (Movie.movie_id, Movie.stock_number) NOT IN (
SELECT Rental.movie_id,
COUNT(Rental.return_status) AS number_of_unreturned
FROM Rental
WHERE Rental.return_status = 'Unreturned'
GROUP BY Rental.movie_id
HAVING COUNT (Rental.return_status) > 1) AND Movie.stock_number = 0;
I definitely have movies in Movie table that are not "Unreturend" but I get no rows selected all the time. Any advices or directions to think would be appreciated. Thanks!
I edited this post and added the content of the tables.
INSERT INTO Movie VALUES (1, 1, 'Amblin', 1, 1, 1, CAST('18-Dec-1968' AS DATE), 'G');
INSERT INTO Movie VALUES (2, 2, 'Duel', 2, 1, 2, CAST('13-Nov-1971' AS DATE), 'R');
INSERT INTO Movie VALUES (3, 3, 'Something Evil ', 3, 1, 3, CAST('21-Jan-1972' AS DATE), 'R');
INSERT INTO Movie VALUES (4, 4, 'The Sugarland Express ', 4, 1, 4, CAST('05-Apr-1974' AS DATE), 'PG13');
INSERT INTO Movie VALUES (5, 5, 'Jaws', 5, 1, 3, CAST('20-Jun-1975' AS DATE), 'R');
INSERT INTO Movie VALUES (6, 6, 'Close Encounters of the Third Kind', 6, 1, 5, CAST('16-Nov-1977' AS DATE), 'PG13');
INSERT INTO Movie VALUES (7, 7, ' 1941', 7, 1, 6, CAST('14-Dec-1979' AS DATE), 'G');
INSERT INTO Movie VALUES (8, 8, 'Raiders of the Lost Ark', 8, 1, 7, CAST('12-Jun-1981' AS DATE), 'PG13');
INSERT INTO Movie VALUES (9, 9, 'E.T. the Extra-Terrestrial', 9, 1, 5, CAST('11-Jun-1982' AS DATE), 'PG13');
INSERT INTO Movie VALUES (10, 10, 'Twilight Zone: The Movie', 10, 1, 3, CAST('24-Jun-1983' AS DATE), 'R');
INSERT INTO Movie VALUES (11, 11, 'Indiana Jones and the Temple of Doom', 11, 1, 7, CAST('23-May-1984' AS DATE), 'PG13');
INSERT INTO Movie VALUES (12, 12, 'The Color Purple', 12, 1, 4, CAST('18-Dec-1985' AS DATE), 'G');
INSERT INTO Movie VALUES (13, 13, 'Empire of the Sun', 13, 1, 4, CAST('25-Dec-1987' AS DATE), 'G');
INSERT INTO Movie VALUES (14, 14, 'Always', 14, 1, 4, CAST('22-Dec-1989' AS DATE), 'G');
INSERT INTO Movie VALUES (15, 15, 'Indiana Jones and the Last Crusade', 15, 1, 7, CAST('24-May-1989' AS DATE), 'G');
INSERT INTO Movie VALUES (16, 16, 'Hook', 16, 1, 8, CAST('11-Dec-1991' AS DATE), 'G');
INSERT INTO Movie VALUES (17, 17, 'Jurassic Park ', 17, 1, 5, CAST('11-Jun-1993' AS DATE), 'PG13');
INSERT INTO Movie VALUES (18, 18, 'Schindler''s List', 18, 1, 4, CAST('15-Dec-1993' AS DATE), 'PG13');
INSERT INTO Movie VALUES (19, 19, 'The Lost World: Jurassic Park', 19, 1, 5, CAST('23-May-1997' AS DATE), 'PG13');
INSERT INTO Movie VALUES (20, 20, 'Amistad', 20, 1, 4, CAST('10-Dec-1997' AS DATE), 'PG13');
INSERT INTO Movie VALUES (21, 21, 'Saving Private Ryan', 21, 1, 4, CAST('24-Jul-1998' AS DATE), 'PG13');
INSERT INTO Movie VALUES (22, 22, 'A.I. Artificial Intelligence', 22, 1, 4, CAST('29-Jun-2001' AS DATE), 'PG13');
INSERT INTO Movie VALUES (23, 23, 'Minority Report', 23, 1, 7, CAST('21-Jun-2002' AS DATE), 'PG13');
INSERT INTO Movie VALUES (24, 24, 'Catch Me If You Can', 24, 1, 8, CAST('25-Dec-2002' AS DATE), 'PG13');
INSERT INTO Movie VALUES (25, 25, ' The Terminal', 25, 1, 4, CAST('18-Jun-2004' AS DATE), 'G');
INSERT INTO Movie VALUES (26, 26, 'War of the Worlds', 26, 1, 5, CAST('29-Jun-2005' AS DATE), 'PG13');
INSERT INTO Movie VALUES (27, 27, 'Munich', 27, 1, 4, CAST('23-Dec-2005' AS DATE), 'PG13');
INSERT INTO Movie VALUES (28, 28, 'Indiana Jones and the Kingdom of the Crystal Skull', 28, 1, 7, CAST('22-May-2008' AS DATE), 'PG13');
INSERT INTO Movie VALUES (29, 29, 'The Adventures of Tintin', 28, 1, 7, CAST('21-Dec-2011' AS DATE), 'PG13');
INSERT INTO Movie VALUES (30, 30, 'War Horse', 30, 1, 4, CAST('25-Dec-2011' AS DATE), 'PG13');
INSERT INTO Movie VALUES (31, 31, 'Lincoln', 31, 1, 4, CAST('09-Nov-2012' AS DATE), 'PG13');
INSERT INTO Movie VALUES (32, 32, 'Bridge of Spies', 32, 1, 4, CAST('16-Oct-2015' AS DATE), 'PG13');
INSERT INTO Movie VALUES (33, 33, 'The BFG', 33, 1, 8, CAST('01-Jul-2016' AS DATE), 'PG13');
INSERT INTO Movie VALUES (34, 34, 'Praying with Anger', 34, 2, 5, CAST('12-Sep-1992' AS DATE), 'PG13');
INSERT INTO Movie VALUES (35, 35, 'Wide Awake', 35, 2, 4, CAST('20-Mar-1998' AS DATE), 'G');
INSERT INTO Movie VALUES (36, 36, 'The Sixth Sense', 36, 2, 2, CAST('06-Aug-1999' AS DATE), 'PG13');
INSERT INTO Movie VALUES (37, 37, 'Unbreakable', 37, 2, 2, CAST('22-Nov-2000' AS DATE), 'PG13');
INSERT INTO Movie VALUES (38, 38, 'Signs', 38, 2, 2, CAST('02-Aug-2002' AS DATE), 'PG13');
INSERT INTO Movie VALUES (39, 39, 'The Village', 39, 2, 2, CAST('30-Jul-2004' AS DATE), 'PG13');
INSERT INTO Movie VALUES (40, 40, 'Lady in the Water', 40, 2, 8, CAST('21-Jul-2006' AS DATE), 'PG13');
INSERT INTO Movie VALUES (41, 41, 'The Happening', 41, 2, 2, CAST('13-Jun-2008' AS DATE), 'R');
INSERT INTO Movie VALUES (42, 42, 'The Last Airbender', 42, 2, 7, CAST('02-Jul-2010' AS DATE), 'G');
INSERT INTO Movie VALUES (43, 43, 'After Earth', 43, 2, 7, CAST('31-May-2013' AS DATE), 'G');
INSERT INTO Movie VALUES (44, 44, 'The Visit', 44, 2, 3, CAST('11-Sep-2015' AS DATE), 'R');
INSERT INTO Movie VALUES (45, 45, 'Split', 45, 2, 2, CAST('20-Jan-2017' AS DATE), 'PG13');
and
INSERT INTO Rental VALUES (sequence_rental.NEXTVAL, 1, 1, 'Delivered', 'Unreturned');
INSERT INTO Rental VALUES (sequence_rental.NEXTVAL, 2, 1, 'Delivered', 'Unreturned');
INSERT INTO Rental VALUES (sequence_rental.NEXTVAL, 3, 6, 'Delivered', 'Unreturned');
INSERT INTO Rental VALUES (sequence_rental.NEXTVAL, 4, 7, 'Delivered', 'Unreturned');
INSERT INTO Rental VALUES (sequence_rental.NEXTVAL, 2, 2, 'Delivered', 'Unreturned');
INSERT INTO Rental VALUES (sequence_rental.NEXTVAL, 2, 37, 'Delivered', 'Unreturned');
INSERT INTO Rental VALUES (sequence_rental.NEXTVAL, 5, 1, 'Delivered', 'Unreturned');
INSERT INTO Rental VALUES (sequence_rental.NEXTVAL, 5, 24, 'Delivered', 'Unreturned');
INSERT INTO Rental VALUES (sequence_rental.NEXTVAL, 5, 3, 'Delivered', 'Unreturned');
INSERT INTO Rental VALUES (sequence_rental.NEXTVAL, 6, 13, 'Delivered', 'Unreturned');
INSERT INTO Rental VALUES (sequence_rental.NEXTVAL, 6, 2, 'Delivered', 'Unreturned');
INSERT INTO Rental VALUES (sequence_rental.NEXTVAL, 6, 8, 'Delivered', 'Unreturned');
INSERT INTO Rental VALUES (sequence_rental.NEXTVAL, 6, 1, 'Delivered', 'Unreturned');
INSERT INTO Rental VALUES (sequence_rental.NEXTVAL, 5, 2, 'Delivered', 'Unreturned');
INSERT INTO Rental VALUES (sequence_rental.NEXTVAL, 5, 3, 'Delivered', 'Unreturned');
INSERT INTO Rental VALUES (sequence_rental.NEXTVAL, 3, 27, 'Delivered', 'Returned');
Sorry if that is a too long post.
I don't want to write the code since you are a student. I'll give some direction though. In your where clause you're comparing (movie.movie_id = rental.movie_id) and (movie.stock_number = count(rental.return_status). Comparing the stock_number to the count of returns is incorrect.
When returning columns from multiple tables, use a join. The in statement does a comparison. Count is not being returned.
Join movies and the "in" subquery on movie_id. Create an alias on the subquery so you can join it.
Add the count column to the topmost outer select
Please try, if this logic is correct, I did not quite understand column naming. You might change last row (having) to correct it.
SELECT
m.movie_id, m.title, m.stock_number -- Getting movie id, movie title, stock number
FROM Movie m -- from movie table
JOIN rental r
ON (m.movie_id = r.movie_id) -- joining rental table in movie_id
WHERE
r.return_status = 'Unreturned' -- where return_status is unreturned
GROUP BY
m.movie_id, m.title, m.stock_number -- grouping_by (same as select)
HAVING
SUM(r.movie_id) > m.stock_number; -- restricting group by quantity
To resolve the query try first to break it down in the components you need.
In this case you need to compare the number of rented movies against the stock of movies.
So write 2 separte queries:
1 - One that will provide the movie id and the number to movies in stock.
2 - Another for the movie id and the number of rentals. For this one you have to count the unretured.
After you have the two queries, you can use them as subqueries of a higer level query that treats each or these queries as a table joined by the common id field.
And add awhere clause comparing the stock with the counted field.
Example:
Table A: id, name, age
Table B: table_b_id, table_a_id, telephone, address
Query 1: select id, name, age from A
Query 2: select table_a_id, telephone, address from B
select Q1.id, Q1.name, Q1.age, Q2telephone, Q2.address
from
(select A.id, A.name, A.age from A) Q1,
(select B.table_a_id, B.telephone, B.address from B) Q2
where
Q1.id = Q2.table_a_id

Subqueries With Multiple Tables

Good day, need your help on my Vehicle Inspection Database. You can see below the structure, you can see it also in here http://sqlfiddle.com/#!3/4ab7e . What I need from this is to extract The Number of Vehicles With Atleast One (1) Defect or Violation Per PROJECT. In the schema below The Total for Project 4 = two (2) vehicles AND Project 9 = 1 vehicle.
Columns Needed are [Project_Name],[Vehicle_Type],[yy],[mm],[Total]
-- Vehicle Inspection Database --
-- Vehicle_Type Table
CREATE TABLE VehicleType
([VehicleTypeId] int,
[Type] varchar (36));
INSERT INTO VehicleType ([VehicleTypeId],[Type])
VALUES (1, 'Light Vehicle'),
(2, 'Tanker'),
(3, 'Goods');
-- Car Table
CREATE TABLE Vehicle
([VehicleID] varchar(36),
[PlateNo] varchar(36),
[VehicleTypeId] int,
[Project] int);
INSERT INTO Vehicle ([VehicleID], [PlateNo],[VehicleTypeId], [Project])
VALUES('A57D4151-BD49-4B44-AF10-000F1C298E05', '8112AG', 1, 4),
('C7095628-AE88-4DD0-A4FD-00363EAB767F', '60070 AD2', 2, 9),
('E714CCD7-E56C-46A8-89D5-003CA5BF6094', '68823 AD1', 3, 9);
-- Event Table
CREATE TABLE Event
([EventID] int,
[VehicleID] varchar(36),
[EventTime] smalldatetime,
[TicketStatus] varchar (10)) ;
INSERT INTO Event([EventID], [VehicleID], [EventTime], TicketStatus)
VALUES (1, 'A57D4151-BD49-4B44-AF10-000F1C298E05', '20130701', 'Open'),
(2, 'A57D4151-BD49-4B44-AF10-000F1C298E05', '20130702', 'Close'),
(3, 'A57D4151-BD49-4B44-AF10-000F1C298E05', '20130703', 'Close'),
(4, 'C7095628-AE88-4DD0-A4FD-00363EAB767F','20130705', 'Open'),
(5, 'C7095628-AE88-4DD0-A4FD-00363EAB767F','20130710', 'Open');
-- Event_Defects Table
CREATE TABLE EventDefects
([EventDefectsID] int,
[EventID] int,
[Status] varchar(15),
[DefectID] int) ;
INSERT INTO EventDefects ([EventDefectsID], [EventID], [Status], [DefectID])
VALUES
-- 1st Inspection for PlateNo. 8112AG
(1, 1, 'YES', 1),
(2, 1, 'NO', 2),
(3, 1, 'YES',3),
(4, 1, 'N/A', 4),
(5, 1, 'N/A', 5),
-- 2nd Inspection for PlateNo. 8112AG
(6, 2, 'NO', 1),
(7, 2, 'NO', 2),
(8, 2, 'NO', 3),
(9, 2, 'N/A', 4),
(10,2, 'N/A', 5),
-- 3rd Inspection for PlateNo. 8112AG
(11, 3, 'NO', 1),
(12, 3, 'NO', 2),
(13, 3, 'NO', 3),
(14, 3, 'NO', 4),
(15, 3, 'NO', 5),
-- 1st Inspection for PlateNo. 60070 AD2
(16, 3, 'NO', 1),
(17, 3, 'NO', 2),
(18, 3, 'NO', 3),
(19, 3, 'N/A', 4),
(20, 3, 'N/A', 5);
-- Defects Table
CREATE TABLE Defects
([DefectID] int,
[DefectsName] varchar (36),
[DefectClassID] int) ;
INSERT INTO Defects ([DefectID], [DefectsName], [DefectClassID])
VALUES (1, 'TYRE', 1),
(2, 'BRAKING SYSTEM', 1),
(3, 'MIRRORS AND WINDSCREEN', 2),
(4, 'OVER SPEEDING', 3),
(5, 'NOT WEARING SEATBELTS', 3);
-- Defect_Class Table
CREATE TABLE DefectClass
([Description] varchar (15),
[DefectClassID] int) ;
INSERT INTO DefectClass ([DefectClassID], [Description])
VALUES (1, 'CATEGORY A'),
(2, 'CATEGORY B'),
(3, 'CATEGORY C');
Do all the joins as inner joins... and it'll eliminate records that are empty.
Can you check if this works for you?
SELECT Vehicle.VehicleID from Vehicle
INNER JOIN Event ON Vehicle.VehicleID = Event.VehicleID
INNER JOIN EventDefects ON EventDefects.EventID = Event.EventID
INNER JOIN Defects ON EventDefects.DefectID = Defects.DefectID
GROUP BY Vehicle.VehicleID;