I have an ecommerce site wherby customers login and see prices for various products. Each customer has their own pricelist and the the prices can be set a number of ways (sources). The table is below:
CREATE TABLE customer_price_list (
customer_price_id int(11) NOT NULL AUTO_INCREMENT,
customer_account_id int(11) NOT NULL,
product_id int(11) DEFAULT NULL,
currency_id int(11) DEFAULT NULL,
customer_price decimal(7,2) DEFAULT NULL,
source enum('TRADE_DEFAULT','TEMPLATE','SAGE','MANUAL') DEFAULT NULL,
PRIMARY KEY (customer_price_id),
KEY customer_account_id (customer_account_id),
KEY product_id (product_id),
KEY currency_id (currency_id),
KEY source (source)
)
Taking just the product_id, customer_price and source, sample data for one customer may look like (using a string for product_id just for illustration) :
Prod_1, 10.00, TRADE_DEFAULT
Prod_2, 20.00, TRADE_DEFAULT
Prod_3, 25.00, MANUAL
And a different customer:
Prod_1, 7.50, SAGE
Prod_2, 20.00, TRADE_DEFAULT
Prod_3, 30.00, TRADE_DEFAULT
The basic price for something, without a discount, is when the source is TRADE_DEFAULT - the above shows these two customers had the TRADE_DEFAULT price for two items each but got a discount on one item.
The TRADE_DEFAULT prices are set by importing a CSV file which has product_id, currency_id and customer_price in it. Within PHP I loop through all the rows in the CSV and bind the values to this query:
insert into customer_price_list
(customer_price_id, customer_account_id, product_id, currency_id, customer_price, source)
select 0, customer_account_id, :product_id, :currency_id, :price, 'TRADE_DEFAULT' from customer_account
This works fine when customer_price_list is empty (for all product_id/currency_id combinations within the CSV). But, if some customers already have product_id/currency_id entries this will result in extra rows (i.e. there will be two or more prices for a product for that customer)
So, when processing the CSV I want to:
A) update any existing TRADE_DEFAULT to the new value from the CSV (again run from a loop of the CSV contents)
update customer_price_list set customer_price = :price
where currency_id=:currency_id and product_id=:product_id and source ='TRADE_DEFAULT'
B) insert a TRADE_DEFAULT price if that customer has no price for that product/currency
insert (ONLY IF NO PRICE OF ANY SOURCE IS THERE) into customer_price_list
(customer_price_id, customer_account_id, product_id, currency_id, customer_price, source)
select 0, customer_account_id, :product_id, :currency_id, :price, 'TRADE_DEFAULT' from customer_account
This is where I need help. I have searched for conditional insert queries but I can only find where they are inserting one recoord like this:
insert into table1 (user,rating,last_modified)
select 'user1', 1999, NOW() from table1
where not exists (
select * from table1
where last_modified > '2007-04-13 08:52:41'
and user='user1'
) limit 1
But I am wanting to do insert .. select and do an inseret, if needed, for all customers.
Thanks.
Try using merge:
https://learn.microsoft.com/en-us/sql/t-sql/statements/merge-transact-sql
It may be helpful with your case as it allows to insert values based on condition and update if they already exist.
Using #Stavr00 suggestion I came up with this:
First add an index across three columns to make product/currency unique for each customer:
alter table customer_price_list add UNIQUE INDEX unq_cust_prod (customer_account_id ASC, product_id ASC, currency_id ASC)
Then change the query:
insert into customer_price_list
(customer_price_id, customer_account_id, product_id, currency_id, customer_price, source)
select 0, customer_account_id, :product_id, :currency_id, :price, 'TRADE_DEFAULT' from customer_account
ON DUPLICATE KEY UPDATE customer_price=customer_price;
By making the update set the price to the current value, the query becomes just the conditional insert. When combined with the update query in step A in my question, it does what I want.
I guess I could have used the ON DUPLICATE KEY UPDATE to do the work of the other query and do it all on one. But, I would only want to update existing records of source = TRADE_DEFAULT so not sure how to do that.
Also, it seems I could have used insert ignore, but as this would not flag some real errors like type mismatch, I thought my solution was safer.
Comments welcome!
I have record like this pic, PLEASE CLICK TO SHOW PIC
how to get like this pic, PLEASE CLICK TO SHOW PIC
create table query:
create table lap ( no_faktur varchar(30) primary key, tgl_jual date,
kd_barang varchar(20), nm_barang varchar(100), harga_beli int (20),
harga_jual int(20), jum_jual int(10) );
insert table query:
insert into lap values ('FJ-2013001','2013-10-01','B-001','laptop
Apple','500000','700000','2'); insert into lap values
('FJ-2013002','2012-10-01','B-002','laptop
Apple','300000','500000','4'); insert into lap values
('FJ-2013003','2013-10-03','B-001','laptop
Apple','500000','700000','1'); insert into lap values
('FJ-2013004','2013-10-11','B-003','HDD 500
GB','700000','800000','1'); insert into lap values
('FJ-2013005','2012-10-01','B-001','laptop
Apple','500000','700000','3'); insert into lap values
('FJ-2013006','2013-10-04','B-004','MONITOR
14"','100000','800000','2'); insert into lap values
('FJ-2013007','2013-02-01','B-001','laptop
Apple','700000','850000','4'); insert into lap values
('FJ-2013008','2013-10-21','B-005','HDD 500
GB','800000','900000','3'); insert into lap values
('FJ-2013009','2013-10-27','B-001','laptop
Apple','500000','700000','1');
I think like this:
select
no_faktur,tgl_jual,kd_barang,nm_barang,harga_jual,jum_jual,sum(harga_jual*jum_jual) as total_jual from lap where month(tgl_jual)='10' and
year(tgl_jual)='2013' and jum_jual=(select max(jum_jual) from lap
group by kd_barang) order by total_jual desc;
But doesn't work because *jum_jual more than 1 rows.
Please help, thanks in advance
select no_faktur,tgl_jual,kd_barang,nm_barang,harga_jual,sum(jum_jual) as jum_jual,sum(harga_jual*jum_jual) as total_jual
from lap where month(tgl_jual)='10' and year(tgl_jual)='2013'
group by kd_barang
order by total_jual desc;
I get an error message that says "#1136 - Column count doesn't match value count at row 1" when I try to insert the values below. Is there any way to have the lines of data that are shorter automatically insert as null at the end without manually going into each line of code?
VALUES ('','BUF','','QB1','','QB BILLS','Face=0x52','#0','25','69','13','13','56','81','81','81','3','12','3');
VALUES ('','BUF','','QB2','frank REICH','Face=0x22','#14','25','69','13','13','31','44','25','50','3','3','2');
VALUES ('','BUF','','RB1','thurman THOMAS','Face=0x83','#34','38','69','63','25','75','50','10','7','8','8');
VALUES ('','BUF','','RB2','jamie MUELLER','Face=0x51','#41','44','69','25','88','50','25','5','3','6','2');
VALUES ('','BUF','','RB3','kenneth DAVIS','Face=0xa5','#23','38','69','25','19','50','31','5','2','7','2');
VALUES ('','BUF','','RB4','don SMITH','Face=0x8b','#30','38','69','25','19','50','31','3','3','8','2');
VALUES ('','BUF','','WR1','james LOFTON','Face=0x81','#80','25','69','38','13','50','56','1','8','13','6');
VALUES ('','BUF','','WR2','andre REED','Face=0xb6','#83','25','69','56','13','56','69','1','9','10','10');
VALUES ('','BUF','','WR3','don BEEBE','Face=0x40','#82','25','69','44','13','50','44','1','4','13','2');
VALUES ('','BUF','','WR4','al EDWARDS','Face=0x9a','#85','25','69','19','13','50','44','1','4','7','2');
VALUES ('','BUF','','TE1','keith MCKELLER','Face=0xb7','#84','25','69','38','50','50','50','1','6','7','6');
VALUES ('','BUF','','TE2','pete METZELAARS','Face=0x50','#88','25','69','19','44','50','31','1','3','5','2');
VALUES ('','BUF','','C','kent HULL','Face=0x1e','#67','25','69','38','69');
VALUES ('','BUF','','LG','jim RITCHER','Face=0x7','#51','25','69','38','56');
VALUES ('','BUF','','RG','john DAVIS','Face=0x24','#65','25','69','25','63');
VALUES ('','BUF','','LT','will WOLFORD','Face=0x48','#69','25','69','25','50');
VALUES ('','BUF','','RT','howard BALLARD','Face=0x88','#75','25','69','19','63');
VALUES ('','BUF','','RE','bruce SMITH','Face=0x88','#78','44','56','69','75','25','81','116','7');
VALUES ('','BUF','','NT','jeff WRIGHT','Face=0xb','#91','25','31','31','50','19','19','30','7');
VALUES ('','BUF','','LE','leon SEALS','Face=0xac','#96','25','31','38','44','31','50','25','18');
VALUES ('','BUF','','ROLB','darryl TALLEY','Face=0xad','#56','31','44','50','38','44','63','25','25');
VALUES ('','BUF','','RILB','ray BENTLEY','Face=0x30','#50','25','31','38','38','31','56','13','10');
VALUES ('','BUF','','LILB','shane CONLAN','Face=0x2f','#58','31','44','50','56','19','69','13','13');
VALUES ('','BUF','','LOLB','c. BENNETT','Face=0x82','#97','38','50','63','63','19','69','29','7');
VALUES ('','BUF','','RCB','nate ODOMES','Face=0xc3','#37','38','44','56','38','38','56','0','25');
VALUES ('','BUF','','LCB','kirby JACKSON','Face=0x89','#47','25','31','44','38','50','50','0','64');
VALUES ('','BUF','','FS','mark KELSO','Face=0x26','#38','31','38','50','38','44','44','2','39');
VALUES ('','BUF','','SS','leonard SMITH','Face=0x84','#46','31','38','50','44','44','50','2','40');
VALUES ('','BUF','','K','scott NORWOOD','Face=0x29','#11','56','81','81','31','44','44','6');
VALUES ('','BUF','','P','rick TUTEN','Face=0x20','#10','25','56','44','31','19','63','3');
Remove the unwanted column from your mysql statement
for example
mysqli_query($con,"INSERT INTO files (1, 2, unwanted, 4)
VALUES ('$01', '$02', '' ,'$04')");
make it
mysqli_query($con,"INSERT INTO files (1, 2, 4)
VALUES ('$01', '$02' ,'$04')");
or Add a variable which is null,
<?php
$null = '';
VALUES ('$null','BUF','$null','ROLB','darryl TALLEY','Face=0xad','#56','31','44','50','38','44','63','25','25');
?>
I have made the following assumptions base on your current post. I assume you want to add the score of a football player to the same table as the fixed data from each player. I would not recommend this because you will continue to add a new column every time you like to add a score.
I have made the following example for you how you can make a score table and player table that will separates the fixed data like name of the player, picture, etc from the scores.
Try this:
SQL query:
SELECT players.name, group_concat(score.score)
FROM players
JOIN score
ON players.id = score.id_players
GROUP BY players.id;
CREATE TABLE players (
id int auto_increment primary key,
name varchar(30)
);
CREATE TABLE score (
id int auto_increment primary key,
score int,
id_players int
);
INSERT INTO players (name)
VALUES ('QB BILLS'), ('frank REICH');
INSERT INTO score (id_players, score)
VALUES (1,25),(1,69), (1,13),(1,13),(1,56),(1,81),(1,81),
(1,81),(1,3),(1,12),(1,3), (2,25),(2,69),(2,13),(2,13),(2,31),(2,44),(2,25),(2,50),(2,3),(2,3),(2,2);
SQLFiddle demo