MySQL Duplicate on Insert - mysql

First table
$sql = "CREATE TABLE if not exists mainInfo (
sku varchar(20) primary key not null,
name varchar(20) not null,
price int(30) not null,
type int(2) not null
)";
Second Table
$sql="CREATE TABLE if NOT EXISTS properties (
size int(9),
bWeight int(9),
fHeight int(9),
fWeight int(9),
fLenght int(9),
sku varchar(20) not null,
CONSTRAINT FK_mainInfoProperties FOREIGN KEY (sku) REFERENCES mainInfo(sku)
)";
Inner join table
$sql = "CREATE TABLE if NOT EXISTS allInfo (
sku varchar(20) primary key not null,
name varchar(20) not null,
price int(30) not null,
type int(2) not null,
size int(9),
bWeight int(9),
fHeight int(9),
fWeight int(9),
fLenght int(9)
)";
$sql = "INSERT INTO allInfo (sku, name, price, type, size, bWeight,
fHeight, fWeight, fLenght)
SELECT mainInfo.sku, name, price, type, size, bWeight, fHeight,
fWeight, fLenght
FROM mainInfo INNER JOIN properties
ON mainInfo.sku = properties.sku";
First time i use this code it works, but when i add new rows to first and second table, inner join table doesn't update it, giving me duplicate entry for key 'PRIMARY' how can i update this table adding new rows but leaving the ones that are already there untouched?

Mark Suk Field in allInfo as foreign key and add new primary key like allInfoId to identify record uniquely

I think you don't need third table. You easily get the unique record using simple join .
Select m.sku ,a.bWeight, a.fHeight, a.fWeight , a.fLenght from mainfon join properties a on m.sku=a.suk where a.suk=your_id
I suggested two use only two table,don't use second one

Related

Didnt display results in database

I have a little problem with one database. I have already entered data in the individual tables in the database. The problem is that with this code, it displays the column names, but didnt return rows. I can't find the error. I think the problem is in JOIN itself. Any ideas for solving the problem?
SELECT cars.brand,
cars.model,
cars.yearofproduction,
cars.engine_type,
parts.part_name,
parts.price AS MONEY,
parts.quantity
FROM CATALOG
JOIN parts
ON parts.part_name = parts.id
JOIN cars
ON CATALOG.car_id = cars.id
WHERE quantity >= '0'
HAVING MONEY < (
SELECT AVG(price)
FROM cars
);
And here the tables. I've already insert values in the tables.
CREATE TABLE CATALOG.parts
(
id INT AUTO_INCREMENT PRIMARY KEY,
part_name VARCHAR(255) NOT NULL,
price DECIMAL NOT NULL,
DESCRIPTION VARCHAR(255) DEFAULT NULL,
quantity TINYINT DEFAULT 0
);
CREATE TABLE CATALOG.cars
(
id INT AUTO_INCREMENT PRIMARY KEY,
brand VARCHAR(255) NOT NULL,
model VARCHAR(255) NOT NULL,
yearofproduction YEAR NOT NULL,
engine_type SET('Diesel', 'A95', 'Gas', 'Metan')
);
CREATE TABLE CATALOG.catalog
(
part_id INT NOT NULL,
CONSTRAINT FOREIGN KEY(part_id) REFERENCES parts(id)
ON DELETE RESTRICT ON UPDATE CASCADE,
car_id INT NOT NULL,
CONSTRAINT FOREIGN KEY(car_id) REFERENCES cars(id)
ON DELETE RESTRICT ON UPDATE CASCADE,
PRIMARY KEY(part_id, car_id)
);

sql JOIN cause double rows

I have two tables that i need to join them
first table i created using this sql query
CREATE TABLE `users` (
`id` bigint PRIMARY KEY AUTO_INCREMENT,
`user_login` varchar(60),
`user_pass` varchar(255),
`first_name` varchar(30),
`last_name` varchar(30),
`user_status` int(2),
`user_phone_number` varchar(20),
`user_email` varchar(100),
`user_billing_info` text,
`user_temp_units` int(2),
`user_flow_units` int(2),
`user_notes` text
);
second table
CREATE TABLE `station_meta` (
`uid` VARCHAR(25) PRIMARY KEY,
`nickname` varchar(30),
`install_date` date,
`latatude` numeric(10,6),
`longitude` numeric(10,6),
`firmware_ver` varchar(10),
`weir_type` int(2),
`weir_width` numeric,
`dist_to_ground` numeric,
`dist_to_weir` numeric,
`service_fee` numeric,
`notes` text
);
i got double rows when i use this sql query
SELECT * FROM station_meta JOIN users
note: uid is something like 9C9Z454Z5CA in case it need to mention it
so there's not any column that is the same in the other table
UPDATE
Data sample
My results
I'm using it in php function in foreach, so i got double results
Appreciate any help
seems you miss a relation between the two tables ..
if you want avoid cartesian product and retrieve just a matching value between the two table you should add a relation as
table user_station_meta (
`id` bigint PRIMARY KEY AUTO_INCREMENT,
user_id bigint
station_meta_uid VARCHAR(25)
)
once you have inserted the matching values
uid, id
9c2748.. 1
BC8CD4.. 5
you can select single matching result as
select u.*. s.*
from user_station_meta us
JOIN station_meta s on s.uid = us.uid
JOIN users u on u.id = us.id

Query gets data from two different users when I try to get data just from just one user

I want to get data just from only one specific user but I get data from both users. Why is that? I don't understand. How can I solve this?.
I have three tables:
/*User*/
CREATE TABLE `User` (
`IDUser` INT NOT NULL AUTO_INCREMENT,
`Name` VARCHAR(50) NOT NULL,
PRIMARY KEY (`IDUser`)
);
/*Category*/
CREATE TABLE `Category` (
`IDCategory` CHAR(3) NOT NULL,
`FK_User` INT NOT NULL,
`CategoryName` VARCHAR(40) NOT NULL,
PRIMARY KEY (`IDCategory`, `FK_User`)
);
/*Product*/
CREATE TABLE `Product` (
`IDProduct` VARCHAR(18) NOT NULL,
`FK_User` INT NOT NULL,
`ProductName` VARCHAR(150) NOT NULL,
`FK_Category` CHAR(3) NOT NULL,
PRIMARY KEY (`IDProduct`, `FK_User`)
);
ALTER TABLE `Product` ADD FOREIGN KEY (`FK_User`) REFERENCES `User`(`IDUser`);
ALTER TABLE `Product` ADD FOREIGN KEY (`FK_Category`) REFERENCES `Category`(`IDCategory`);
ALTER TABLE `Category` ADD FOREIGN KEY (`FK_User`) REFERENCES `User`(`IDUser`);
insert into User(Name) values('User1');
insert into User(Name) values('User2');
insert into Category(IDCategory,FK_User,CategoryName) values('CT1',1,'Category1User1');
insert into Category(IDCategory,FK_User,CategoryName) values('CT1',2,'Category1User2');
If two different users insert both the same product with the same ID:
insert into Product values('001',1,'shoe','CT1');
insert into Product values('001',2,'shoe','CT1');
Why do I keep getting data from both users if I try a query like this one:
SELECT P.IDProduct,P.ProductName,P.FK_Category,C.CategoryName
FROM Product P inner join Category C on P.FK_Category=C.IDCategory
WHERE P.FK_User=1
this is the result I get:
You are getting two rows because both categories have the same IDCategory value which is the value you are JOINing on. You need to also JOIN on the FK_User values so that you don't also get User2's category values:
SELECT P.IDProduct,P.ProductName,P.FK_Category,C.CategoryName
FROM Product P
INNER JOIN Category C ON P.FK_Category=C.IDCategory AND P.FK_User = C.FK_User
WHERE P.FK_User=1
You need to add p.FK_User=C.Fk_User this condition in your join clause
SELECT P.IDProduct,P.ProductName,P.FK_Category,C.CategoryName
FROM Product P inner join Category C
on P.FK_Category=C.IDCategory and p.FK_User=C.Fk_User
WHERE P.FK_User=1
A PRIMARY KEY is a UNIQUE key. Shouldn't CategoryID be unique? That is, shouldn't Category have PRIMARY KEY(CategoryId)?
(Check other tables for a similar problem.)

MYSQL: left Join and sum two tables where one table has two columns referring to the first table

I am trying to create a procedure where my transfer table is joined to my account table. In my transfer table, there are two FK columns that reference the account table id column.
account table:
CREATE TABLE account (
id INT NOT NULL AUTO_INCREMENT,
name VARCHAR(30) NOT NULL,
number VARCHAR(30) NOT NULL DEFAULT '',
description VARCHAR(255)NOT NULL DEFAULT '',
is_active BIT(1) NOT NULL DEFAULT b'1',
PRIMARY KEY (id),
UNIQUE account_name (name, number)
);
transfer table:
CREATE TABLE transfer (
id INT NOT NULL AUTO_INCREMENT,
date DATE NOT NULL,
from_account INT NULL,
to_account INT NULL,
amount DECIMAL(12, 2) NOT NULL,
PRIMARY KEY (id),
FOREIGN KEY (from_account)
REFERENCES account(id),
FOREIGN KEY (to_account)
REFERENCES account(id)
);
get_account procedure:
CREATE PROCEDURE get_account()
SELECT a.*,
(SUM(t.amount) - SUM(f.amount)) AS balance
FROM account a
LEFT JOIN transfer f
ON a.id = f.from_account
LEFT JOIN transfer t
ON a.id = t.to_account
GROUP BY a.id;
I am trying to subtract the total of the from_accout column from the total of the to_account column. I am able to get the sum of just one column but when I try to get both it returns a NULL.
This seems like it should be easy, but I can't figure it out.

SQL select entries in other table linked by foreign keys

I have redesigned my database structure to use PRIMARY and FOREIGN KEYs to link the entries in my 3 tables together, and I am having problems trying to write queries to select data in one table given data in a another table. Here is an example of my 3 CREATE TABLE statements:
CREATE TABLE IF NOT EXISTS players (
id INT(10) NOT NULL AUTO_INCREMENT,
username VARCHAR(16) NOT NULL,
uuid VARCHAR(200) NOT NULL DEFAULT 0,
joined TIMESTAMP DEFAULT 0,
last_seen TIMESTAMP DEFAULT 0,
PRIMARY KEY (id)
);
/* ^
One |
To
| One
v
*/
CREATE TABLE IF NOT EXISTS accounts (
id INT(10) NOT NULL AUTO_INCREMENT,
account_id INT(10) NOT NULL,
pass_hash VARCHAR(200) NOT NULL,
pass_salt VARCHAR(200) NOT NULL,
created BIGINT DEFAULT 0,
last_log_on BIGINT DEFAULT 0,
PRIMARY KEY (id),
FOREIGN KEY (account_id) REFERENCES players(id) ON DELETE CASCADE
) ENGINE=InnoDB;
/* ^
One |
To
| Many
v
*/
CREATE TABLE IF NOT EXISTS purchases (
id INT(10) NOT NULL AUTO_INCREMENT,
account_id INT(10) NOT NULL,
status VARCHAR(20) NOT NULL,
item INT NOT NULL,
price DOUBLE DEFAULT 0,
description VARCHAR(200) NOT NULL,
buyer_name VARCHAR(200) NOT NULL,
buyer_email VARCHAR(200) NOT NULL,
transaction_id VARCHAR(200) NOT NULL,
payment_type VARCHAR(20) NOT NULL,
PRIMARY KEY (id),
FOREIGN KEY (account_id) REFERENCES accounts(account_id) ON DELETE CASCADE
) ENGINE=InnoDB;
Say for example, I want to select all the usernames of users who purchased anything greater than $30. All the usernames are stored in the players table, which is linked to the accounts table and that is linked to the purchases table. Is this this the best way to design this relational database? If so, how would I run queries similar to the above example?
I was able to get get all of a users purchase history given their username, but I did it with 2 sub-queries... Getting that data should be easier than that!
Here is the SELECT query I ran to get all of a players purchase data:
SELECT *
FROM purchases
WHERE account_id = (SELECT id FROM accounts WHERE account_id = (SELECT id FROM players WHERE username = 'username'));
Also, when I try to make references to the other tables using something like 'players.username', I get an error saying that the column doesn't exist...
I appreciate any help! Thanks!
Your design is ok in my opinion. The relation between players and account is one-to-many and not one-to-one since this way, you can have two tuples referencing a single player.
I would write the query you need as:
SELECT DISTINCT p.id, p.username
FROM players p INNER JOIN accounts a ON (p.id = a.account_id)
INNER JOIN purchases pc ON (a.id = pc.account_id)
WHERE (pc.price > 30);
As Sam suggested, I added DISTINCT to avoid repeating id and username in case a user have multiple purchases.
Note the id is here to avoid confusion among repeated usernames.