There are two tables:
create table author (id int primary key auto_increment, name varchar(255));
insert into author (name) values ('tingwei');
insert into author (name) values ('jiahui');
insert into author (name) values ('naidan');
insert into author (name) values ('weizhi');
insert into author (name) values ('siyao');
create table book (author_id int primary key auto_increment, book varchar(255));
insert into book (book) values ('I love you');
insert into book (book) values ('I hate you');
insert into book (book) values ('I miss you');
But I don't know what does this statement mean by using number 1 behind "select":
select *
from author
where exists (select 1 from book where book.author_id = author.id)
I've already searched some information online but I got nothing.
SELECT 1 does just that: it selects the value 1. When used with WHERE EXISTS it does not matter what data the subquery returns, as long as it returns any data (in other words: returns at least one row).
Related
CREATE TABLE Movies (
ID int PRIMARY KEY,
Title varchar(50),
Director varchar(50),
Year int ,
Length_minutes decimal(5,2)
);
Here is the insert statement:
INSERT INTO Movies VALUES (1,'Toy Story','John Lasseter',1995,81) ;
INSERT INTO Movies VALUES (2,'A Bug\'s life','John Lasseter',1998,95) ;
INSERT INTO Movies VALUES (3,'Toy','John Lasseter',1999,93) ;
INSERT INTO Movies VALUES (4,'Monsters,Inc','Pete Docter',2001,92) ;
INSERT INTO Movies VALUES (5,'Finding Nemo','Andrew Stanton',2003,107) ;
Schema Error: Error: ER_PARSE_ERROR: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'INSERT INTO Movies VALUES (3,'Toy Story 2 ','John Lasseter',1999,93) ; INSERT I' at line 4
The insert statements after id2 don't work.
Primary Keys cannot be repeated. If you are inserting the same one again that is an issue.
MySQL table creation
CREATE TABLE movies(
id INT UNSIGNED AUTO_INCREMENT, PRIMARY KEY(id),
title VARCHAR(250),
director VARCHAR(250),
year TINYINT,
minutes TINYINT
)ENGINE=InnoDB;
Since the id is a PRIMARY KEY that AUTO_INCREMENTs, you will have to label all of your fields.
MySQL insertion (only use on first insert)
INSERT movies (title, director, year, minutes) VALUES('Toy Story 2', 'John Lasseter', 1999, 93);
MySQL update
UPDATE movies SET title='Toy Story 2', director='John Lasseter', year=1999, minutes=93 WHERE id=3;
I see the issue from the INSERT statement is here:
INSERT INTO Movies VALUES (2,'A Bug\'s life','John Lasseter',1998,95) ;
There are two ways you can do this either escaping the single quote with another single quote like '' or replace the opening and closing single quotes to double quotes. Look at this two example:
INSERT INTO Movies VALUES (2,'A Bug''s life','John Lasseter',1998,95) ;
INSERT INTO Movies VALUES (6,"A Bug's life","John Lasseter",1998,95) ;
Fiddle: https://www.db-fiddle.com/f/DfwTYpTr8Xj3McLi9KZNZ/2
Try :
INSERT INTO Movies (ID, Title, Director, Year, Length_minutes) VALUES (3,'Toy Story 2','John Lasseter',1999,93) ;
I have a question for an assignment with 5 tables as shown below. I need to write a query with the minimum cost for each sport:
2nd column is equipment_name:
I think I need to do a bunch of joins in subqueries with the primary keys being the id columns and the foreign keys the name_id columns. Is this the right approach?
You don't need a bunch of joins; minimally this question can be solved by one join between the store_equipment_price and the sports_equipment tables - if these two are joined on equipment id then you'll effectively get rows that can give the cost of starting up in each sport per store. You'll need to group by the sport id and the store id; don't forget that it might be cheaper to start soccer by getting all the gear from store A but it might be cheaper to start golf by going to tore B - tho I how I read the question. If however you're prepared to get your gloves from store A and your bat from store B etc then we don't even group by the store when summing, instead we work out which store is cheapest for each component rather than which store is cheapest for each sport overall.
If you're after producing named stores/sports on your result rows then you'll need more joins but try getting the results right based on the fewest number of joins possible to start with
Both these queries will ultimately be made a lot easier by the use of an analytic/windowing function but these are database dependent; never post an sql question up without stating what your db vendor is, as there are few questions that are pure ISO SQL
You question is not completely clear, I assume you need to find stores from which to buy each equipment for all sports so as to incur minimum expense. Following query will achieve this
select s.sports, e.equipment_name, min(sep.price),
(select store_name from stores st where st.id = sep.store_id) store_name
from sports s
join sports_equipment se on s.id = se.sport_id
join equipment e on e.id = se.equipment_id
join sports_equipment_prices sep on sep.equipment_id = se.equipment_id
group by s.sports, e.equipment_name
order by s.sports, e.equipment_name
;
Following 'create table' and 'insert data' script are based on your screen images
create table sports (
id INTEGER PRIMARY KEY AUTOINCREMENT,
sports varchar(50)
);
insert into sports(sports) values('golf');
insert into sports(sports) values('baseball');
insert into sports(sports) values('soccer');
create table stores (
id INTEGER PRIMARY KEY AUTOINCREMENT,
store_name varchar(50)
);
insert into stores(store_name) values('A');
insert into stores(store_name) values('B');
insert into stores(store_name) values('C');
create table equipment (
id INTEGER PRIMARY KEY AUTOINCREMENT,
equipment_name varchar(50)
);
insert into equipment(equipment_name) values('shoes');
insert into equipment(equipment_name) values('ball');
insert into equipment(equipment_name) values('clubs');
insert into equipment(equipment_name) values('glove');
insert into equipment(equipment_name) values('bat');
create table sports_equipment (
sport_id INTEGER not null,
equipment_id INTEGER not null,
FOREIGN KEY(sport_id) REFERENCES sports(id),
FOREIGN KEY(equipment_id) REFERENCES equipment(id)
);
insert into sports_equipment values(1, 1);
insert into sports_equipment values(1, 2);
insert into sports_equipment values(1, 3);
insert into sports_equipment values(2, 2);
insert into sports_equipment values(2, 4);
insert into sports_equipment values(2, 5);
insert into sports_equipment values(3, 1);
insert into sports_equipment values(3, 2);
create table sports_equipment_prices (
id INTEGER PRIMARY KEY AUTOINCREMENT,
store_id INTEGER not null,
equipment_id INTEGER not null,
price INTEGER not null,
FOREIGN KEY(store_id) REFERENCES stores(id),
FOREIGN KEY(equipment_id) REFERENCES equipment(id)
);
I have 6 columns in my table:
Id | Name | Mail id | Gender | Contact Number | father name
while inserting a data into table i wanted to check condition like if Name,mailid,contact number already exists then insert should not happen else record should be inserted.
Can any one suggest how to check the condition while inserting a record.
IF NOT EXISTS (SELECT * FROM Table_Name WHERE Condition you are checking)
BEGIN
INSERT INTO ............. ---<----- Your Insert Statement.....
END
You can define an index on multiple columns, e.g.:
CREATE UNIQUE INDEX arbitrary_index_name ON table_name (Name, mailid, contactnumber);
I also faced similar situation, you can do this by adding unique constraint to your table and using 'insert ignore' statement to add data.
Create table statement:
CREATE TABLE Student (
Id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(50),
Mailid VARCHAR(50),
Gender CHAR,
contactnumber BIGINT,
fathername VARCHAR(50),
UNIQUE(NAME,Mailid,contactnumber));
Insert Ignore statement:
INSERT IGNORE INTO student(NAME, Mailid,Gender,contactnumber,fathername) VALUES('Shekhar', 's#s.com', 'M', 987654321, 'Joshi');
I have a table called 'users' that contains fields such as
username
DOB
gender
etc
Each user can save their plants on a table called 'plants' that has the following fields
username
plant
So user 'johndoe' would show on table 'plants' as follows:
johndoe -> lilly
johndoe -> orchid1
johndoe -> orchid2
johndoe -> fern1
johndoe -> fern2
Questions:
Is this a bad way of setting up my tables? I ask because when the number of users grows, then there will be hundreds of rows, several of which with repeated usernames because each user will likely have more than one plant. Would this slow down queries?
If I make one plant table per user, I think that would increase dramatically the number of DB requests and create an enormous amount of tables in the DB.
Another option would be to have separate tables for lilly, orchid, fern, etc with fields such as
username
but then I would still have several rows with repeated usernames.
Any suggestions?
Normalize your tables. Add id field to users and store that id in plants instead of the username.
Further, read more about normalization principles and try to apply them in practice.
In stead of using the username I would use an INT id. Like so:
userid
username
DOB
gender
etc
and for your plants:
plantid
userid_fk
plantname
And then join on users.userid = plants.userid_fk to find the matches :)
That's a perfectly reasonable way (your initial proposal) to set things up; that's what relational databases are for.
You're doing a classic many-to-many relationship in your plants table. Each user can have several plants, and each plant may have several users.
For better efficiency, you could use an id to refer to your users instead of a user name. In most relational databases, an id is a row number, and is a very efficient (and compact) reference.
Here's how I'd go about this, with an example database script and query:
Create/Load Users Table - Using a surrogate primary key instead of the username since queries will be faster against INTs and they can conceivably change.
CREATE TABLE users (
id int(11) AUTO_INCREMENT NOT NULL,
username varchar(255) NOT NULL,
gender char(1) NULL,
PRIMARY KEY(id)
) ENGINE = MyISAM AUTO_INCREMENT = 3
Load Users
INSERT INTO users(id, username, gender)
VALUES(1, 'john', NULL)
GO
INSERT INTO users(id, username, gender)
VALUES(2, 'jane', NULL)
GO
Create Plants
CREATE TABLE plants (
id int(11) AUTO_INCREMENT NOT NULL,
name varchar(200) NOT NULL,
PRIMARY KEY(id)
) ENGINE = MyISAM AUTO_INCREMENT = 6
Load Plants
INSERT INTO plants(id, name)
VALUES(1, 'fern1')
GO
INSERT INTO plants(id, name)
VALUES(2, 'fern2')
GO
INSERT INTO plants(id, name)
VALUES(3, 'orchid1')
GO
INSERT INTO plants(id, name)
VALUES(4, 'orchid2')
GO
INSERT INTO plants(id, name)
VALUES(5, 'lilly1')
Create Join Table I use a surrogate primary key here since so many web platforms won't properly update a join table with a 2 column primary. Also, I've ended up adding meta data / details to these types of joins quite often, and it gets messy without it. Note I don't restrict the combination of the same user adding the same plant type, but you can easily.
CREATE TABLE plants_users (
id int(11) AUTO_INCREMENT NOT NULL,
plant_id int(11) NOT NULL,
user_id int(11) NOT NULL,
PRIMARY KEY(id)
)
ENGINE = MyISAM
AUTO_INCREMENT = 8
GO
CREATE INDEX fk_plant_id USING BTREE
ON plants_users(plant_id)
GO
CREATE INDEX fk_user_id USING BTREE
ON plants_users(user_id)
Load Join Table
INSERT INTO plants_users(id, plant_id, user_id)
VALUES(1, 1, 1)
GO
INSERT INTO plants_users(id, plant_id, user_id)
VALUES(2, 2, 1)
GO
INSERT INTO plants_users(id, plant_id, user_id)
VALUES(3, 3, 1)
GO
INSERT INTO plants_users(id, plant_id, user_id)
VALUES(4, 4, 1)
GO
INSERT INTO plants_users(id, plant_id, user_id)
VALUES(5, 2, 2)
GO
INSERT INTO plants_users(id, plant_id, user_id)
VALUES(6, 3, 2)
GO
INSERT INTO plants_users(id, plant_id, user_id)
VALUES(7, 5, 2)
Final Query:
select
users.username,
plants.name
from
users,plants,plants_users
where
users.id = plants_users.user_id and
plants.id = plants_users.plant_id
Result:
user name
john fern1
john fern2
john orchid1
john orchid2
jane fern2
jane orchid1
jane lilly1
This may have a really easy answer. I have done much database stuff for a while. I am trying to get the auto_increment value from one table inserted into the value on another table. is there an easy way of doing this. For eg i have done:
CREATE TABLE table_a (
id int NOT NULL AUTO_INCREMENT,
a_value varchar(4),
PRIMARY KEY (id)
);
CREATE TABLE table_b (
id int NOT NULL,
b_value varchar(15),
FOREIGN KEY (id) REFERENCES table_a (id)
);
Now i want to insert values into the table but I would like 'id' values for table_a and table_b to be the same. So far i have:
INSERT INTO table_a VALUES (NULL, 'foobar');
But I do not know how to go about extracting the auto_incermented 'id' number from table_a into the 'id' value of table_b. I have looked at SELECT #id = LAST_INSERT_ID() but can not get it to work.
You cannot do that at once. You'll have to first insert into the first table:
INSERT INTO table_a (a_value) VALUES ('foobar');
and then insert into the second using the generated id:
INSERT INTO table_b (id, b_value) VALUES (##IDENTITY, 'foobar');
LAST_INSERT_ID() and no need for the select statement part.