I am a beginner in SQL and am having difficulty understanding the logic query. In this particular problem, I am trying to find the Track that was purchased in California.
Here are the tables.
CREATE TABLE [InvoiceLine]
(
[InvoiceLineId] INTEGER NOT NULL,
[InvoiceId] INTEGER NOT NULL,
[TrackId] INTEGER NOT NULL,
[UnitPrice] NUMERIC(10,2) NOT NULL,
[Quantity] INTEGER NOT NULL,
CONSTRAINT [PK_InvoiceLine] PRIMARY KEY ([InvoiceLineId]),
FOREIGN KEY ([InvoiceId]) REFERENCES [Invoice] ([InvoiceId])
ON DELETE NO ACTION ON UPDATE NO ACTION,
FOREIGN KEY ([TrackId]) REFERENCES [Track] ([TrackId])
ON DELETE NO ACTION ON UPDATE NO ACTION
);
CREATE TABLE [Invoice]
(
[InvoiceId] INTEGER NOT NULL,
[CustomerId] INTEGER NOT NULL,
[InvoiceDate] DATETIME NOT NULL,
[BillingAddress] NVARCHAR(70),
[BillingCity] NVARCHAR(40),
[BillingState] NVARCHAR(40),
[BillingCountry] NVARCHAR(40),
[BillingPostalCode] NVARCHAR(10),
[Total] NUMERIC(10,2) NOT NULL,
CONSTRAINT [PK_Invoice] PRIMARY KEY ([InvoiceId]),
FOREIGN KEY ([CustomerId]) REFERENCES [Customer] ([CustomerId])
ON DELETE NO ACTION ON UPDATE NO ACTION
);
CREATE TABLE [Track]
(
[TrackId] INTEGER NOT NULL,
[Name] NVARCHAR(200) NOT NULL,
[AlbumId] INTEGER,
[MediaTypeId] INTEGER NOT NULL,
[GenreId] INTEGER,
[Composer] NVARCHAR(220),
[Milliseconds] INTEGER NOT NULL,
[Bytes] INTEGER,
[UnitPrice] NUMERIC(10,2) NOT NULL,
CONSTRAINT [PK_Track] PRIMARY KEY ([TrackId]),
FOREIGN KEY ([AlbumId]) REFERENCES [Album] ([AlbumId])
ON DELETE NO ACTION ON UPDATE NO ACTION,
FOREIGN KEY ([GenreId]) REFERENCES [Genre] ([GenreId])
ON DELETE NO ACTION ON UPDATE NO ACTION,
FOREIGN KEY ([MediaTypeId]) REFERENCES [MediaType] ([MediaTypeId])
ON DELETE NO ACTION ON UPDATE NO ACTION
);
Here is what I've tried.
SELECT T.name
FROM Track T, InvoiceLine L
WHERE T.trackid=L.trackid AND
L.invoiceid IN (SELECT I.invoiceid
FROM Invoice I
WHERE I.billingcity="California");
The query returns nothing. What is wrong with the logic?
SELECT
T.name
FROM Track T
INNER JOIN InvoiceLine L ON T.trackid = L.trackid
INNER JOIN invoice I ON L.InvoiceId = I.InvoiceId
WHERE I.BillingState = 'California'
Track joins to InvoiceLine which joins to Invoice
Please do NOT use the ancient way of joining through the where clause. The simplest trick for this is to disallow any commas between table e.g. note the comma in: FROM Track T, InvoiceLine L - avoid those.
I assume you want the state of California held in BillingState not a city of that name (if one exists).
Related
I am working on the basic chinook database, and am trying to write a sqlite query to create a view called v10BestSellingArtists for the 10 bestselling artists based on the total quantity of tracks sold (named as TotalTrackSales) order by TotalTrackSales in descending order. TotalAlbum is the number of albums with tracks sold for each artist.
I can write queries for both of them separately, but I can't figure out how to merge them.
But I want one query with the columns: Artist, TotalAlbum TotalTrackSales.
Can anyone tell me how to do this using only one select statement?
Any help is appreciated.
The schema for the album table:
[Title] NVARCHAR(160) NOT NULL,
[ArtistId] INTEGER NOT NULL,
FOREIGN KEY ([ArtistId]) REFERENCES "artists" ([ArtistId])
artists table :
[ArtistId] INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
[Name] NVARCHAR(120)
tracks table schema:
[TrackId] INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
[Name] NVARCHAR(200) NOT NULL,
[AlbumId] INTEGER,
[MediaTypeId] INTEGER NOT NULL,
[GenreId] INTEGER,
[Composer] NVARCHAR(220),
[Milliseconds] INTEGER NOT NULL,
[Bytes] INTEGER,
[UnitPrice] NUMERIC(10,2) NOT NULL,
FOREIGN KEY ([AlbumId]) REFERENCES "albums" ([AlbumId])
ON DELETE NO ACTION ON UPDATE NO ACTION,
FOREIGN KEY ([GenreId]) REFERENCES "genres" ([GenreId])
ON DELETE NO ACTION ON UPDATE NO ACTION,
FOREIGN KEY ([MediaTypeId]) REFERENCES "media_types" ([MediaTypeId])
ON DELETE NO ACTION ON UPDATE NO ACTION
table invoice_items:
[InvoiceLineId] INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,
[InvoiceId] INTEGER NOT NULL,
[TrackId] INTEGER NOT NULL,
[UnitPrice] NUMERIC(10,2) NOT NULL,
[Quantity] INTEGER NOT NULL,
FOREIGN KEY ([InvoiceId]) REFERENCES "invoices" ([InvoiceId])
ON DELETE NO ACTION ON UPDATE NO ACTION,
FOREIGN KEY ([TrackId]) REFERENCES "tracks" ([TrackId])
ON DELETE NO ACTION ON UPDATE NO ACTION
We’re trying to delete all rows that have data for Account name= Banana Republic....
So far we have:
Delete Account_T
From Account_T
Join Program_T
Where Account_T.AccountName = Program_T.AccountName
And AccountName = ‘Banana Republic’
Here are the tables:
create table Program_T
(AccountName varchar(150) not null unique,
ProgramID int not null,
Revenue int,
Advocates int,
Shares int,
Conversions int,
Impressions int,
LaunchDate date,
CSMID int not null,
constraint Program_PK primary key (AccountName, CSMID),
constraint Program_FK1 foreign key (AccountName) references Account_T(AccountName),
constraint Program_FK2 foreign key (CSMID) references CSM_T(CSMID));
and Account_T table:
create table Account_T
(AccountName varchar(150) not null unique,
Health varchar(10) not null,
EcommercePlatform varchar(50),
CSMID int not null,
Industry varchar(50),
Amount int not null,
constraint Accounts_PK primary key (AccountName),
constraint Accounts_FK foreign key (CSMID) references CSM_T(CSMID));
Why not just do two deletes?
delete a from Account_T a
where AccountName = 'Banana Republic';
delete p from Program_T p
where AccountName = 'Banana Republic';
You used the bad character before and after Banana Republic.
Write the query like this :
DELETE Account_T
FROM Account_T AS A
JOIN Program_T AS P
ON A.AccountName = P.AccountName
Where A.AccountName = 'Banana Republic'
I wrote DELETE, but don't forget to always test with a SELECT first !
Use the ON clause with your JOIN instead of the jointure condition in the WHERE, its important to respect this.
I am trying to create three tables such as associate, manager and attendance. The attendance table should be having employee and manager details from the other two table which should enable marking the attendance. I created this SQL script. I'm not sure where I am making mistake.
CREATE TABLE associate (
id INT NOT NULL,
idmanager INT NOT NULL,
emp_id DATE NOT NULL,
emp_name VARCHAR(25) NOT NULL,
FOREIGN KEY (id) REFERENCES attendance (associate_id) ON DELETE CASCADE,
FOREIGN KEY (idmanager) REFERENCES attendance (manager_idmanager) ON DELETE CASCADE,
PRIMARY KEY (id)
) ENGINE=INNODB;
CREATE TABLE manager (
id INT NOT NULL,
mgr_usr_id VARCHAR(15) NOT NULL,
mgr_name VARCHAR(25) NOT null,
KEY (id),
KEY (mgr_usr_id),
FOREIGN KEY (id) REFERENCES associate (idmanager) ON DELETE CASCADE,
PRIMARY KEY (id)
) ENGINE=INNODB;
CREATE TABLE attendance (
sno INT NOT NULL,
manager_idmanager INT NOT NULL,
associate_id INT NOT NULL,
date_stamp DATETIME,
state BIT NOT NULL,
PRIMARY KEY (sno)
) ENGINE=INNODB;
Screenshot
It's an issue of ordering. For example, the first statement executed is
CREATE TABLE associate (
which references attendance. However, the attendance table has not yet been created. Switch the order so that any tables that reference other tables come last.
Alternatively, don't put the FOREIGN KEY constraints in the CREATE statements, but them at the end of your script with ALTER TABLE statements. Consider:
CREATE TABLE associate (
id INT NOT NULL,
idmanager INT NOT NULL,
emp_id DATE NOT NULL,
emp_name VARCHAR(25) NOT NULL,
PRIMARY KEY (id)
) ENGINE=INNODB;
CREATE TABLE attendance (
sno INT NOT NULL,
manager_idmanager INT NOT NULL,
associate_id INT NOT NULL,
date_stamp DATETIME,
state BIT NOT NULL,
PRIMARY KEY (sno)
) ENGINE=INNODB;
ALTER TABLE associate ADD FOREIGN KEY (id) REFERENCES associate(id) ON DELETE CASCADE;
Edit
The above is just syntax. To model the requested problem consider orthogonality of information. You might also see/hear "normalization." The basic concept is this: have only one copy of your information. The schema should have a single point of authority for all data. For example, if a user has a birthdate, make sure you don't have an ancillary column that also stores their birthday; it's superfluous information and can lead to data errors.
In this case, what is the relationship? What must come first for the other to exist? Can an attendance be had without a manager? How about a manager without attendance? The former makes no sense. In this case then, I would actually use a third table, to form a hierarchy.
Then, consider that maybe roles change in a company. It would not behoove the DB architect to hard code roles as tables. Consider:
CREATE TABLE employee (
id INTEGER NOT NULL AUTO_INCREMENT,
name VARCHAR(25) NOT NULL,
PRIMARY KEY (id)
) ENGINE=INNODB;
CREATE TABLE role (
id INTEGER NOT NULL AUTO_INCREMENT,
name VARCHAR(30) NOT NULL,
description VARCHAR(254) NOT NULL,
PRIMARY KEY( id ),
UNIQUE( name )
) ENGINE=INNODB;
INSERT INTO role (name, description) VALUES
('associate', 'An associate is a ...'),
('manager', 'A manager follows ...');
CREATE TABLE employee_role (
employee_id INTEGER NOT NULL,
role_id INTEGER NOT NULL,
PRIMARY KEY (employee_id, role_id),
FOREIGN KEY (idemployee_id) REFERENCES employee_id (id) ON DELETE CASCADE,
FOREIGN KEY (role_id) REFERENCES role (id) ON DELETE CASCADE
) ENGINE=INNODB;
CREATE TABLE attendance (
sno INTEGER NOT NULL,
employee_id INTEGER NOT NULL,
date_stamp DATETIME,
state BIT NOT NULL,
PRIMARY KEY (sno),
FOREIGN KEY (idemployee_id) REFERENCES employee_id (id) ON DELETE CASCADE
) ENGINE=INNODB;
From this schema, the attendance needs only one foreign key because everyone is an employee. Employee's can have multiple roles, and they can change. Further, role definitions can change without needing to resort to costly DDL statements (data definition layer changes, like ALTER TABLE), and can be modified with simple DML (data manipulation layer changes, like UPDATE TABLE). The former involves rewriting all entries in the tables, and changing schemas, while the latter involves changing individual entries.
My teacher provided me with this sql code, and I logged in as root into phpmyadmin, added a database called webstore, and then tried to add this code and it's giving me errors. Is there anyone who can tell me what could be causing the errors? I am using a Mac, so I'm not sure if that makes any difference, I can give you a link to dropbox with additional information if necessary.
This is the dropbox link with the code provided (Webstore.sql): https://www.dropbox.com/sh/usfmbeyxqd2q1g5/AADoLFbsz8cL30EC76d60i40a?dl=0
Also, the zip file contains images of the errors I was receiving. PLEASE HELP!!
The SQL statement the error occurs on is
CREATE TABLE Shopping_Cart (
CustID INTEGER NOT NULL,
ProdID INTEGER NOT NULL,
NumOfItems INTEGER,
PRIMARY KEY CLUSTERED (CustID, ProdID)
CONSTRAINT FK_Cust FOREIGN KEY FK_Cat (CustID)
REFERENCES Customers (CustID)
ON DELETE RESTRICT
ON UPDATE RESTRICT,
CONSTRAINT FK_Prod FOREIGN KEY FK_Prod (ProdID)
REFERENCES Products (ProdID)
ON DELETE RESTRICT
ON UPDATE RESTRICT
);
The error reads
A comma or closing bracket was expected. (near "CONSTRAINT" at position 153)
Unexpected beginning of statement. (near "CustID" at position 192)
Unrecognised statement type. (near "REFERENCES" at position 206)
Your PRIMARY KEY line needs a comma after it before the CONSTRAINT.
CREATE TABLE Shopping_Cart (
CustID INTEGER NOT NULL,
ProdID INTEGER NOT NULL,
NumOfItems INTEGER,
PRIMARY KEY CLUSTERED (CustID, ProdID),
CONSTRAINT FK_Cust FOREIGN KEY FK_Cat (CustID)
REFERENCES Customers (CustID)
ON DELETE RESTRICT
ON UPDATE RESTRICT,
CONSTRAINT FK_Prod FOREIGN KEY FK_Prod (ProdID)
REFERENCES Products (ProdID)
ON DELETE RESTRICT
ON UPDATE RESTRICT
);
Edit
It turns out there were a lot of problems with the SQL. The tables were created in the wrong order and the data types were wrong. Here is a rewritten version that I have tested out:
DROP DATABASE IF EXISTS WebStore;
CREATE DATABASE WebStore;
USE WebStore;
CREATE TABLE Categories (
CatID INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
Name VARCHAR(20) NOT NULL,
Descr VARCHAR(120) NOT NULL,
IconURL VARCHAR(64) NOT NULL,
PRIMARY KEY (CatID)
);
CREATE TABLE Products (
ProdID INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
Name VARCHAR(20) NOT NULL,
Category INTEGER UNSIGNED,
Descr VARCHAR(120) NOT NULL,
Price FLOAT NOT NULL,
Stock INTEGER UNSIGNED NOT NULL,
IconURL VARCHAR(64) NOT NULL,
PRIMARY KEY (ProdID),
CONSTRAINT FK_Cat FOREIGN KEY FK_Cat (Category)
REFERENCES Categories (CatID)
ON DELETE RESTRICT
ON UPDATE RESTRICT
);
INSERT INTO Categories VALUES(null,"Laptops","Small computers you can carry","http://localhost/images/laptop.jpg");
SET #laptops := LAST_INSERT_ID();
INSERT INTO Categories VALUES(null,"Desktops","Big computers you cannot carry","http://localhost/images/desktop.jpg");
SET #desktops := LAST_INSERT_ID();
INSERT INTO Categories VALUES(null,"Tablets"," Flat things you lose frequently","http://localhost/images/tablet.jpg");
SET #tablets := LAST_INSERT_ID();
INSERT INTO Products VALUES(null,"DULL 1200",#desktops,"A big dull machine",1290.99,23,"http://localhost/images/dull1200.jpg");
INSERT INTO Products VALUES(null,"8P Totalo",#desktops,"Almost as big as the DULL",990.99,2,"http://localhost/images/8ptotalo.jpg");
INSERT INTO Products VALUES(null,"LaNuveau Bingster",#desktops,"Comes in blue and red",690.99,12,"http://localhost/images/lanuveaubingster.jpg");
INSERT INTO Products VALUES(null,"DULL 122",#laptops,"Small, portable and useless",422.99,4,"http://localhost/images/dull122.jpg");
INSERT INTO Products VALUES(null,"8P Tootsie",#laptops,"Sticky and too heavy",559.99,12,"http://localhost/images/8ptootsie.jpg");
INSERT INTO Products VALUES(null,"LaNuveau Shoobie XT",#laptops,"Weighs a ton but looks sharp",1690.99,122,"http://localhost/images/lanuveaushoobiext.jpg");
INSERT INTO Products VALUES(null,"Motor Roller 12",#tablets,"The only one with a oval screen",422.99,4,"http://localhost/images/mr12.jpg");
INSERT INTO Products VALUES(null,"SamSings OffKey",#tablets,"Needs duct tape to run",559.99,2,"http://localhost/images/samsingsOK.jpg");
INSERT INTO Products VALUES(null,"jPet 12",#tablets,"The first that kinda sorta works",16290.99,722,"http://localhost/images/jpet12.jpg");
CREATE TABLE Customers (
CustID INTEGER UNSIGNED NOT NULL AUTO_INCREMENT,
FirstName VARCHAR(40) NOT NULL,
LastName VARCHAR(40) NOT NULL,
Address VARCHAR(60) NOT NULL,
City VARCHAR(40) NOT NULL,
State VARCHAR(20) NOT NULL,
Zip VARCHAR(5) NOT NULL,
PRIMARY KEY (CustID)
);
INSERT INTO Customers VALUES(null,"Gerald","Bostock","1234 TAAB Drive","St. Cleve","FL","12345");
INSERT INTO Customers VALUES(null,"Suzy","Creamcheese","8722 Zappa Road","Paris","TX","75460");
CREATE TABLE Shopping_Cart (
CustID INTEGER UNSIGNED NOT NULL,
ProdID INTEGER UNSIGNED NOT NULL,
NumOfItems INTEGER,
PRIMARY KEY CLUSTERED (CustID, ProdID),
CONSTRAINT FK_Cust FOREIGN KEY FK_Cat (CustID)
REFERENCES Customers (CustID)
ON DELETE RESTRICT
ON UPDATE RESTRICT,
CONSTRAINT FK_Prod FOREIGN KEY FK_Prod (ProdID)
REFERENCES Products (ProdID)
ON DELETE RESTRICT
ON UPDATE RESTRICT
);
INSERT INTO Shopping_Cart VALUES("1","4","2");
INSERT INTO Shopping_Cart VALUES("1","9","1");
I would like some help with an SQL query that I am struggling with, Ive got 90% of what I need it to do done its just the last bit that I'm having a little issue with.
Database Design
I have the following database Schema
CREATE TABLE IF NOT EXISTS EMPLOYEES(
ID INTEGER AUTO_INCREMENT NOT NULL PRIMARY KEY,
FIRST_NAME VARCHAR(255) NOT NULL,
LAST_NAME VARCHAR(255) NOT NULL,
SEX CHAR(1) NOT NULL,
COST INTEGER NOT NULL
);
CREATE TABLE IF NOT EXISTS SKILLS(
ID INTEGER AUTO_INCREMENT NOT NULL PRIMARY KEY,
SKILL VARCHAR(300) NOT NULL
);
CREATE TABLE IF NOT EXISTS EMPLOYEE_SKILLS(
EMPLOYEE_ID INTEGER NOT NULL,
SKILL_ID INTEGER NOT NULL,
PROFICIENCY SET('1','2','3','4') NOT NULL,
PRIMARY KEY(EMPLOYEE_ID,SKILL_ID),
UNIQUE INDEX(SKILL_ID,EMPLOYEE_ID),
FOREIGN KEY (EMPLOYEE_ID) REFERENCES EMPLOYEES(ID) ON UPDATE CASCADE ON DELETE CASCADE,
FOREIGN KEY (SKILL_ID) REFERENCES SKILLS(ID) ON UPDATE CASCADE ON DELETE CASCADE
);
CREATE TABLE IF NOT EXISTS PROJECTS(
ID INTEGER AUTO_INCREMENT NOT NULL PRIMARY KEY,
NAME VARCHAR(300) NOT NULL,
LOCATION VARCHAR(255) DEFAULT NULL,
INCOME INTEGER NOT NULL
);
CREATE TABLE IF NOT EXISTS TASKS(
ID INTEGER AUTO_INCREMENT NOT NULL PRIMARY KEY,
NAME VARCHAR(300) NOT NULL,
PROJECT_ID INTEGER NOT NULL,
DATE_FROM DATE NOT NULL,
DATE_TO DATE NOT NULL,
COMPLETED BOOLEAN DEFAULT 0,
FOREIGN KEY (PROJECT_ID) REFERENCES PROJECTS(ID) ON UPDATE CASCADE ON DELETE CASCADE
);
CREATE TABLE IF NOT EXISTS TASK_SKILLS(
TASK_ID INTEGER NOT NULL,
SKILL_ID INTEGER NOT NULL,
PROFICIENCY_REQUIRED SET('1','2','3','4') NOT NULL,
PRIMARY KEY(TASK_ID,SKILL_ID),
UNIQUE INDEX(SKILL_ID,TASK_ID),
FOREIGN KEY (TASK_ID) REFERENCES TASKS(ID) ON UPDATE CASCADE ON DELETE CASCADE,
FOREIGN KEY (SKILL_ID) REFERENCES SKILLS(ID) ON UPDATE CASCADE ON DELETE CASCADE
);
CREATE TABLE IF NOT EXISTS ASSIGNED_TO(
EMPLOYEE_ID INTEGER NOT NULL,
TASK_ID INTEGER NOT NULL,
DATE_ASSIGNED DATETIME NOT NULL,
PRIMARY KEY(EMPLOYEE_ID,TASK_ID),
UNIQUE INDEX(TASK_ID,EMPLOYEE_ID),
FOREIGN KEY (EMPLOYEE_ID) REFERENCES EMPLOYEES(ID) ON UPDATE CASCADE ON DELETE CASCADE,
FOREIGN KEY (TASK_ID) REFERENCES TASKS(ID) ON UPDATE CASCADE ON DELETE CASCADE
);
Query
So the query that I would like to create would be to return every EMPLOYEE within the database along with their SKILLS and the PROFICIENCY of their skill. This was the part of the query where I had no trouble with and I have the following query:
SELECT EMPLOYEES.ID, CONCAT_WS(' ',EMPLOYEES.FIRST_NAME,EMPLOYEES.LAST_NAME) AS NAME, GROUP_CONCAT(SKILLS.SKILL),EMPLOYEES.COST,GROUP_CONCAT(EMPLOYEE_SKILLS.PROFICIENCY)
FROM EMPLOYEE_SKILLS
JOIN EMPLOYEES ON EMPLOYEE_SKILLS.EMPLOYEE_ID = EMPLOYEES.ID
JOIN SKILLS ON EMPLOYEE_SKILLS.SKILL_ID = SKILLS.ID
GROUP BY EMPLOYEES.ID
The above query gives me the majority of what I want, where it returns every employee within the database and their associated skill and the level that they know it at.
The thing that I am struggling with now is that I would also like to join up this query to also look into the ASSIGNED_TO table of the database as well, where I would like to find all the employees within the organisation (assigned to a task or not) and return the TASK ID that they have been assigned and the start and end date of said task.
Ive tried simply adding another join to the ASSIGNED_TOtable within the above query but it doesn't give me the desired output. I'm suspecting because I am grouping by the employee id. Would I need to use something like two queries to get what I want, for example and inner select and an outer select and do an inner join between them? Not really sure what the approach would be for this query.
Sorry for the long post and any help will be much appreciated.
Thanks.