I am practicing making Databases and tables, so I made a database for baseball info containing a table for Teams and Region they are from (not listed to accuracy). The teams show fine, but when I execute command SELECT * FROM region, it shows me all the columns of ID, name, region, but only has a null value. Code below:
CREATE DATABASE baseball;
USE baseball;
CREATE TABLE teams(
id INT NOT NULL AUTO_INCREMENT,
name VARCHAR(255) NOT NULL,
PRIMARY KEY (id)
);
CREATE TABLE region (
id INT NOT NULL AUTO_INCREMENT,
region_name VARCHAR(255),
teams_id INT NOT NULL,
PRIMARY KEY (id),
FOREIGN KEY (teams_id) REFERENCES teams(id)
);
INSERT INTO teams (name)
VALUES ('Yankees'), ('Red Sox'), ('Mets');
SELECT * FROM teams;
INSERT INTO region (region_name, teams_id)
VALUES ('NorthEast', 1),
('Northeast', 2),
('Central', 3),
('West', 4);
SELECT * FROM region;
Also, the names of teams repeat as well the more I mess with it, something is redundant about this. Thanks.
Related
CREATE TABLE CU_ORDER
( cordernumber INT PRIMARY KEY,
fname_lname VARCHAR(50) NOT NULL,
product_name VARCHAR(100) NOT NULL,
);
CREATE TABLE TRACKING_NUMBER
( trnumber INT PRIMARY KEY
);
INSERT INTO CU_ORDER VALUES(456, 'John Doe' , Table);
INSERT INTO TRACKING_NUMBER(276734673);
I am trying to created a table called Package and in the table it will have all the items from cu_order and all the items from tracking_number. How will I add all of the attributes of this table to one table. What am I doing wrong?
CREATE TABLE PACKAGE
( orderno INT PRIMARY KEY,
fname VARCHAR(50) NOT NULL,
name VARCHAR(100) NOT NULL,
trno INT PRIMARY KEY);
INSERT INTO PACKAGE (........
The two tables do not seem to have a relation, so, presumably, you want a cartesian product of both tables. If so, you can use the insert ... select ... syntax with a cross join:
insert into package(orderno, fname, name, trno)
select
co.cordernumber,
co.fname_lname,
co.product_name,
tn.trnumber
from cu_order co
cross join tracking_number tn
This inserts all possible combinations of rows from both source tables in the target table.
You should also fix the declaration of the package table: yours has two primary keys, which is not allowed. Instead, you probably want a compound primary key made of both columns:
create table package (
orderno int,
fname varchar(50) not null,
name varchar(100) not null,
trno int,
primary key(orderno, trno)
);
You can create a new table from the data of another table (or several tables) by appending a SELECT statement to the CREATE TABLE statement.
However, your two source tables are missing the 1:1 relation allowing this to work, which I assume is the cordernumber of CU_ORDER. It appears the table TRACKING_NUMBER is missing a 'cordernumber' column.
CREATE TABLE TRACKING_NUMBER (
trnumber INT PRIMARY KEY,
cordernumber INT
);
After you added the column 'cordernumber' to TRACKING_NUMBER, you can create the new table PACKAGE with:
CREATE TABLE PACKAGE (
orderno INT PRIMARY KEY,
fname VARCHAR(50) NOT NULL,
name VARCHAR(100) NOT NULL,
trno INT PRIMARY KEY
)
SELECT
CU_ORDER.cordernumber AS orderno,
CU_ORDER.fname_lname AS fname,
CU_ORDER.product_name AS name,
TRACKING_NUMBER.trnumber AS trno
FROM CU_ORDER, TRACKING_NUMBER
WHERE CU_ORDER.cordernumber=TRACKING_NUMBER.cordernumber;
MySQL version 5.5.49, on Linux Mint (Ubuntu 14.04.1 based)
The people table contains all of a family: Jed, David, Sarah, and Luke. The cars table contains the two cars we own. The CarPeople table contains an entry for each person who rides in a car, and contains keys that associate the personID to the carID. Last is the carData table, which contains the color of a car, a personID of someone who last painted the car, an image of the paint job, a date of the paint job, and a url to see the image.
This is a strange example, but the idea is that only people who are associated with specific car id's can paint or ride in the car. The example data I inserted has Jed (1) and David (2) riding together in car 1, while David (2), Luke (3), and Sarah (4) ride in car 2.
The following query result must be contained in a view, where a parameter is passed in which references the personID:
Show the CarID, ImageURL, and all people that ride with the PersonID, but only for the latest DataEntryTime for each CarID.
My people_concat column isn't outputting correct results, but I can fix that later.
My main issue is I can't figure out how to output the data row for the max dataentrytime for each carid within this view. Changes I have tried result in only one row being outputted, I can't figure out how to do this.
The crucial test query is this:
select c.* from (select #p1:=2 p) parm , carRiderList c;
This does a select from the view with respect to user 2, David. Instead of 5 rows, only two should be outputted, the first of CarID 2, and the first of carID 1.
Running these queries should result in one row, the one containg the highest dataentrytime for the associated personID's:
select c.* from (select #p1:=1 p) parm , carRiderList c;
select c.* from (select #p1:=3 p) parm , carRiderList c;
select c.* from (select #p1:=4 p) parm , carRiderList c;
Thank you!(SQL Code is below)
/* People in the database */
create table People
(
PersonID int(11) not null unique auto_increment,
phoneNumber varchar(30) not null unique,
Name varchar(40) not null unique,
PRIMARY KEY (PersonID)
)
ENGINE=InnoDB DEFAULT CHARSET=utf8;
insert into People (phoneNumber, Name)
values ("123-456-7891", "Jed"), ("223-456-7891", "David"), ("323-456-7891", "Luke"), ("423-456-7891", "Sarah");
select * from People;
/* Cars */
drop table if exists Cars;
create table Cars
(
CarID int(11) not null unique auto_increment,
PurchaseTime date,
PRIMARY KEY (CarID)
)
ENGINE=InnoDB DEFAULT CHARSET=utf8;
insert into Cars (PurchaseTime)
values ("2016-1-1"),("2016-1-2");
select * from Cars;
/* CarPerson: Will contain an entry for each person who rides in the car, and can paint it */
drop table if exists CarPerson;
create table CarPerson
(
CarPersonID int(11) not null unique auto_increment,
CarID int(11) not null,
CarRiderID int(11) not null,
PRIMARY KEY (CarPersonID),
FOREIGN KEY (CarID) references Cars(CarID),
FOREIGN KEY (CarRiderID) references People(PersonID)
)
ENGINE=InnoDB DEFAULT CHARSET=utf8;
insert into CarPerson(CarID, CarRiderID)
values (1, 1), (1, 2), (2, 2), (2, 3), (2, 4);
select * from CarPerson;
/* CarData: Contains CarID, the color was that car was painted, and the person who painted it, as well as a (fake) imageurl */
create table carData
(
DataID int(11) not null unique auto_increment,
CarID int(11) not null,
Color varchar(20),
DataEntryTime date,
PainterID int(11) not null,
ImageURL varchar(255),
PRIMARY KEY (DataID),
FOREIGN KEY (CarID) references Cars(CarID),
FOREIGN KEY (PainterID) references People(PersonID)
)
ENGINE=InnoDB DEFAULT CHARSET=utf8;
insert into carData(CarID, Color, DataEntryTime, PainterID, ImageURL)
values (1, "Blue", "2013-1-1", 1, "http://www.bluecivic.com"),
(1, "Green", "2013-1-2", 3, "http://greencivic.com"),
(2, "Red", "2014-1-3", 4, "http://redford.com"),
(2, "Purple", "2014-1-4", 2, "http://purpleford.com"),
(2, "Black","2014-1-5", 3, "http://blackford.com");
select * from carData;
/* View I am having trouble with */
create function p1() returns INTEGER DETERMINISTIC NO SQL return #p1;
drop view carRiderList;
create view carRiderList as
(select distinct cp.CarID, cd.ImageURL, DataEntryTime, (
select group_concat(Name order by CarID, PersonID = p1())from People p
left join CarPerson cp
on p.PersonID = cp.CarPersonID
where cp.CarID IN (
select distinct(CarID)
from CarPerson cp
where cp.CarPersonID = p1()
limit 1
)
)
as people_concat
from CarPerson cp
left join carData cd
on cd.CarID = cp.CarID
where cp.CarRiderID = p1()) order by DataEntryTime desc;
select c.* from (select #p1:=2 p) parm , carRiderList c;
I tried to create a new Database and some Tables and executed Query successfully, but my tables are not visible in Object Explorer, but my Database is created. Refreshed the Object Explorer as well!
Could you please help me sort this out?
Create DATABASE CustomerOrders
GO
USE CustomerOrders;
GO
CREATE TABLE dbo.Customerdetails
(
Customer_ID int IDENTITY(1,1) PRIMARY KEY,
Name varchar(50) NOT NULL,
PhoneNumber int NOT NULL,
Address nvarchar(100)
);
GO
INSERT dbo.Customerdetails
VALUES ('ABC', +91-123456789, 'SF'), ('DEF', +1-123432145, 'California');
GO
CREATE TABLE dbo.Productdetails
(
Product_ID int IDENTITY(2015160,1) PRIMARY KEY,
Product_Name nvarchar(100) NOT NULL,
UnitPrice money NOT NULL,
ISSN_No varchar(100) NOT NULL
);
GO
INSERT dbo.Productdetails
VALUES ('QWERR', 15000, 'ASD123//456'), ('ERRT', 45000, 'APP4352223//234');
GO
CREATE TABLE dbo.Orderdetails
(
Order_ID int IDENTITY(00001,1) PRIMARY KEY,
Cust_ID int NOT NULL,
Prod_ID int NOT NULL,
Quantity int NOT NULL,
ProductName nvarchar(100) NOT NULL,
CONSTRAINT FK_Customer_ID FOREIGN KEY (Cust_ID)
REFERENCES CustomerDetails(Customer_ID),
CONSTRAINT FK_Product_ID FOREIGN KEY (Prod_ID)
REFERENCES ProductDetails(Product_ID)
);
GO
INSERT dbo.Productdetails
VALUES ('Sony_Xperia', 5, 'SWER2525//35'), ('Apple-I series', 2, 'SWER2525//35');
GO
i tried out in my machine.but its working fine.its shows all tables in object explorer.
Just disconnect server and connect again and check it out.
I am working on MySQL database, and I need to select some data with procedure. So I have something like:
CREATE TABLE pet (id INT, name VARCHAR(20), own_id INT);
insert into pet values (1,"Rufus", 1);
insert into pet values (2,"Bali", 1);
insert into pet values (3,"Lolo", 2);
ref pet.own_id = own.id
CREATE TABLE own (id INT, own_name VARCHAR(20), own_color VARCHAR(20));
insert into own values (1,"Me", "Red");
insert into own values (2,"Other" ,"Green");
And now I wonder how to select / join data to get something like that (as results):
own_name own_color name
Me Red Rufus
Me Red Bali
Other Green Lolo
SELECT own_name, own_color, name
from pet
JOIN own on (pet.own_id = own.id)
;
You have only to join both tables:
Select own_name,own_color, name from own join pet on
pet.own_id = own.id
select o.own_name, o.own_color, p.name from own o, pet p
where p.own_id=o.id
It's a JOIN.
While a JOIN is a valid answer, some people find subqueries easier to read and write:
SELECT own_name, own_color, (SELECT name
FROM pet
WHERE pet.own_id = own.id) AS name
FROM own
This is basically the same as the JOIN method, but then as a subquery
I have a suggestion for your tables: own_id is a foreign key, so instead of
CREATE TABLE pet (id INT, name VARCHAR(20), own_id INT);
CREATE TABLE own (id INT, own_name VARCHAR(20), own_color VARCHAR(20));
I'd do:
CREATE TABLE own (
id INT NOT NULL AUTO_INCREMENT,
own_name VARCHAR(20) NOT NULL,
own_color VARCHAR(20) NOT NULL,
PRIMARY KEY (id)
);
CREATE TABLE pet (
id INT NOT NULL AUTO_INCREMENT,
name VARCHAR(20) NOT NULL,
own_id INT NOT NULL,
PRIMARY KEY (id),
FOREIGN KEY (own_id) REFERENCES own (id)
);
I added some other things as well.
Improvements/changes:
I assumed none of the fields should be NULL. I added NOT NULL to all the fields making it impossible for a field to have a value of NULL. (If you want some fields to be allowed to have a value of NULL just remove the NOT NULL from the CREATE TABLE statements.)
I made both id fields increment automatically. This means the insert statements can now be just insert into own (own_name, own_color) values ("Me", "Red"); and the database will automatically keep track of the ids for you.
I added primary keys so the database knows that the rows can be identified by the id fields
I added a foreign key constraint, meaning that every own_id in pet must exist in own. If you try to insert or alter a pet row in a way that breaks this constraint mysql will throw an error at you.
I have two tables, locations and location groups
CREATE TABLE locations (
location_id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(63) UNIQUE NOT NULL
);
INSERT INTO locations (name)
VALUES
('london'),
('bristol'),
('exeter');
CREATE TABLE location_groups (
location_group_id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
location_ids VARCHAR(255) NOT NULL,
user_ids VARCHAR(255) NOT NULL,
name VARCHAR(63) NOT NULL,
);
INSERT INTO location_groups (location_ids, user_ids, name)
VALUES
('1', '1,2,4', 'south east'),
('2,3', '2', 'south west');
What I am trying to do is return all location_ids for all of the location_groups where the given user_id exists. I'm using CSV to store the location_ids and user_ids in the location_groups table. I know this isn't normalised, but this is how the database is and it's out of my control.
My current query is:
SELECT location_id
FROM locations
WHERE FIND_IN_SET(location_id,
(SELECT location_ids
FROM location_groups
WHERE FIND_IN_SET(2,location_groups.user_ids)) )
Now this works fine if the user_id = 1 for example (as only 1 location_group row is returned), but if i search for user_id = 2, i get an error saying the sub query returns more than 1 row, which is expected as user 2 is in 2 location_groups. I understand why the error is being thrown, i'm trying to work out how to solve it.
To clarify when searching for user_id 1 in location_groups.user_ids the location_id 1 should be returned. When searching for user_id 2 the location_ids 1,2,3 should be returned.
I know this is a complicated query so if anything isn't clear just let me know. Any help would be appreciated! Thank you.
You could use GROUP_CONCAT to combine the location_ids in the subquery.
SELECT location_id
FROM locations
WHERE FIND_IN_SET(location_id,
(SELECT GROUP_CONCAT(location_ids)
FROM location_groups
WHERE FIND_IN_SET(2,location_groups.user_ids)) )
Alternatively, use the problems with writing the query as an example of why normalization is good. Heck, even if you do use this query, it will run more slowly than a query on properly normalized tables; you could use that to show why the tables should be restructured.
For reference (and for other readers), here's what a normalized schema would look like (some additional alterations to the base tables are included).
The compound fields in the location_groups table could simply be separated into additional rows to achieve 1NF, but this wouldn't be in 2NF, as the name column would be dependent on only the location part of the (location, user) candidate key. (Another way of thinking of this is the name is an attribute of the regions, not the relations between regions/groups, locations and users.)
Instead, these columns will be split off into two additional tables for 1NF: one to connect locations and regions, and one to connect users and regions. It may be that the latter should be a relation between users and locations (rather than regions), but that's not the case with the current schema (which could be another problem of the current, non-normalized schema). The region-location relation is one-to-many (since each location is in one region). From the sample data, we see the region-user relation is many-many. The location_groups table then becomes the region table.
-- normalized from `location_groups`
CREATE TABLE regions (
`id` INT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
`name` VARCHAR(63) UNIQUE NOT NULL
);
-- slightly altered from original
CREATE TABLE locations (
`id` INT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
`name` VARCHAR(63) UNIQUE NOT NULL
);
-- missing from original sample
CREATE TABLE users (
`id` INT UNSIGNED PRIMARY KEY AUTO_INCREMENT,
`name` VARCHAR(63) UNIQUE NOT NULL
);
-- normalized from `location_groups`
CREATE TABLE location_regions (
`region` INT UNSIGNED,
`location` INT UNSIGNED UNIQUE NOT NULL,
PRIMARY KEY (`region`, `location`),
FOREIGN KEY (`region`)
REFERENCES regions (id)
ON DELETE restrict ON UPDATE cascade,
FOREIGN KEY (`location`)
REFERENCES locations (id)
ON DELETE cascade ON UPDATE cascade
);
-- normalized from `location_groups`
CREATE TABLE user_regions (
`region` INT UNSIGNED NOT NULL,
`user` INT UNSIGNED NOT NULL,
PRIMARY KEY (`region`, `user`),
FOREIGN KEY (`region`)
REFERENCES regions (id)
ON DELETE restrict ON UPDATE cascade,
FOREIGN KEY (`user`)
REFERENCES users (id)
ON DELETE cascade ON UPDATE cascade
);
Sample data:
INSERT INTO regions
VALUES
('South East'),
('South West'),
('North East'),
('North West');
INSERT INTO locations (`name`)
VALUES
('London'),
('Bristol'),
('Exeter'),
('Hull');
INSERT INTO users (`name`)
VALUES
('Alice'),
('Bob'),
('Carol'),
('Dave'),
('Eve');
------ Location-Region relation ------
-- temporary table used to map natural keys to surrogate keys
CREATE TEMPORARY TABLE loc_rgns (
`location` VARCHAR(63) UNIQUE NOT NULL
`region` VARCHAR(63) NOT NULL,
);
-- Hull added to demonstrate correctness of desired query
INSERT INTO loc_rgns (region, location)
VALUES
('South East', 'London'),
('South West', 'Bristol'),
('South West', 'Exeter'),
('North East', 'Hull');
-- map natural keys to surrogate keys for final relationship
INSERT INTO location_regions (`location`, `region`)
SELECT loc.id, rgn.id
FROM locations AS loc
JOIN loc_rgns AS lr ON loc.name = lr.location
JOIN regions AS rgn ON rgn.name = lr.region;
------ User-Region relation ------
-- temporary table used to map natural keys to surrogate keys
CREATE TEMPORARY TABLE usr_rgns (
`user` INT UNSIGNED NOT NULL,
`region` VARCHAR(63) NOT NULL,
UNIQUE (`user`, `region`)
);
-- user 3 added in order to demonstrate correctness of desired query
INSERT INTO usr_rgns (`user`, `region`)
VALUES
(1, 'South East'),
(2, 'South East'),
(2, 'South West'),
(3, 'North West'),
(4, 'South East');
-- map natural keys to surrogate keys for final relationship
INSERT INTO user_regions (`user`, `region`)
SELECT user, rgn.id
FROM usr_rgns AS ur
JOIN regions AS rgn ON rgn.name = ur.region;
Now, the desired query for the normalized schema:
SELECT DISTINCT loc.id
FROM locations AS loc
JOIN location_regions AS lr ON loc.id = lr.location
JOIN user_regions AS ur ON lr.region = ur.region
;
Result:
+----+
| id |
+----+
| 1 |
| 2 |
| 3 |
+----+