I have a table with 2 column say C1 and C2. i need to insert 10 rows where always Columns 2 will be same.
INSERT INTO Table
(C1, C2)
VALUES
(100, 'X'),
(101, 'X'),
(102, 'X'),
(103, 'X'),
(104, 'X'),
(105, 'X'),
(106, 'X');
Is there any other way like below,
INSERT INTO Table
(C1)
VALUES
(100,102,103,104,105,106)
and value of C2 should be X for the inserted rows
Thanks in advance,
You will have to create a table
CREATE TABLE `tblA` (
`C1` INT(10) NULL,
`C2` VARCHAR(50) NULL DEFAULT 'X'
);
Then when you do INSERT INTO Table (C1) VALUES (100,102,103,104,105,106); the column C2 will have 'X' as a value.
There are, but not really very advantageous, one way or the other. If what you're trying to do is to write the constant value only once, I'd try to keep it simple and go for
SET #X := 'X'
or
SELECT #X := expression FROM ...
followed by
INSERT INTO Table
(C1, C2)
VALUES
(100, #X), (102, #X), ...;
You can apply an insert into from a select statement VALUES is hard-coded answers... insert into from select is query based insert. In the sample below, I am using #MySQL variables to create a variable "#num" and start it at 99. Then you just have to substitute per the sample as it describes... Any table that has at least the number of records you want to add. So, in my case, I am only concerned with any table that has AT LEAST 10 records. If you want to add 1000, and have a table with AT LEAST that many records, use that. The LIMIT obviously limits how many records you return from it. Since you are not really using any columns from the table, it doesn't matter what that table is. So, now the #num := #num +1 will keep increasing for every record processed, thus going to 100, 101, 102, etc for the "c1" column, and the 'X' will be constanct for the "c2" column and you are done.
INSERT INTO Table
(C1, C2)
select
#num := #num +1 as c1,
'X' as c2
from
AnyTableThatHasAtLeastNumberOfRecordsYouWant,
( select #num := 99 ) sqlvars
limit
10
Related
I want to do an insert ignore if a column has a specific value.
Say I have a simple table that records changes to a PO over time. Each time the PO is updated, I need to insert a record on this table:
PONum | POLine | submittedBy | ... other columns
100 1 initial-value
100 1 TB
100 2 initial-value
On a PHP page I check for the existence of the PO number in this table. If there isn't one, I insert all the PO lines I find from another table. I set the submittedBy name to "initial-value".
Now later on, say PO Line 3 is added. I want to run through my check again and only insert the new record for line 3 if there isn't already one that has line 3 with a submittedBy of initial-value
INSERT IGNORE INTO PODetailCL (PONum, POLine, submittedBy, ... )
VALUES (100, 1, 'TB', ... ),
(100, 2, 'TB', ...),
(100, 3, 'initial-value', ...)
WHERE submittedBy <> 'initial-value' -- <- something like this but not sure of the syntax
Try using conditional insert multiple rows:
INSERT INTO PODetailCL(PONum, POLine, submittedBy, ... )
SELECT (100, 1, 'TB', ... ), (100, 2, 'TB', ...),(100, 3, 'initial-value', ...)
FROM PODetailCL
WHERE EXISTS (SELECT * FROM PODetailCL WHERE submittedBy <> 'initial-value')
I was able to use a virtual column and then add a unique constraint on that column. After that I can use INSERT IGNORE. (Virtual columns are only available in MySQL version 5.7 or later.)
ALTER TABLE porelcl
ADD COLUMN initialCheck BIT GENERATED ALWAYS
AS (CASE WHEN submittedBy = 'initial-value' THEN b'1' ELSE NULL END)
then after that:
ALTER TABLE porelcl ADD UNIQUE initial_check_index (PONum, POLine, PORelNum, initialCheck)
Now when my code runs through the check again, if tries to insert a duplicate record: SomePO, SomePOLine, SomePORelNum & 'initial-value' the insert won't take place, which is what I need.
I am having trouble, while inserting data from a select statement having scalar function call. I posted sample script below, and little explanation and question in the comments.
---target table (in my case, this is not table variable, but a regular table, here for simplicity to posted this code as table variable to get the idea)
declare #tblItems table (
Id int identity(1,1)
,ItemID int
,TranNo varchar(20)
,Qty decimal(18,3)
,SomeCalculatedValue decimal(18,3)
)
--a dummay temp table, works like a source table
declare #tblTemp table (
Id int identity(1,1)
,ItemID int
,TranNo varchar(20)
,Qty decimal(18,3)
,SomeCalculatedValue decimal(18,3)
)
--put some dummy data in target table
insert into #tblItems(ItemID, TranNo, Qty, SomeCalculatedValue)
values
(1, 'GRN-001', 10, 0),
(2, 'GRN-002', 20, 0),
(3, 'GRN-003', 15, 0),
(4, 'GRN-004', 32, 0),
(5, 'GRN-005', 18, 0)
;
--insert 3 new rows in temp table, which later I want to insert in target table
insert into #tblTemp(ItemID, TranNo, Qty, SomeCalculatedValue)
values
(1, 'GRN-006', 6, 0), -- this line is working work fine,
(1, 'GRN-007', 3, 0), -- but this line is having problem, because it is not considering the last line( with TranNo='GRN-006' )
(2, 'GRN-008', 8, 0)
--here is the actual work, I need to read data from temp table to target table
--and the key requirement is the column 'SomeCalculatedValue'
--it should call a scalar function, and within that function I have to perform some calculations based on same target table
--for each ItemID passed, that scalar function will works as: it performs some sort of calculations on existing rows
--for that particular ItemID, to simplify the understanding you can think of it as Running-Total(not actually running total, but concept
--is same that each row value will based on previous row value)
insert into #tblItems(ItemID, TranNo, Qty, SomeCalculatedValue)
select
ItemID
,TranNo
,Qty
,[dbo].[GetCalculatedValue] (ItemID, Qty) as SomeCalculatedValue -- this function will perform some calcualations
from #tblTemp
select * from #tblItems
I have two tables, #tblItems and #tblTemp. I have to insert rows from #tblTemp to #tblItems, but in the select clause of #tblTemp, I used a scalar function, lets say, GetCalculatedValue(ItemID, Qty), which performs some calculations for specific ItemID from target table, and for each row it calculates a value which should be inserting in the #tblItems. It is not really Running-Total but for the sake for understanding it can think of as running total, because each row value will depend upon last previous lines.
So problem is that when #tblTemp has more than 1 row for a particular ItemID, it should consider the rows already inserted, but I think this insert-into-select statement will insert all rows at once, so it is not considering the last lines for particular ItemID which are in same select statement. You can review the code, I posted some comments also for explanation.
I have a table with something like 100 columns and now I would like to insert a row with some columns equal to some values and default values for all other columns. Is it possible?
Something like:
insert into tablename (col1, col22, col33) values (1, 2, 3)
The columns not listed in the column list will be assigned to their default values.
You can also do:
insert into tablename values (1, default, 3, default, 5, ..., 100)
But nothing I'd do with 100 columns. Too easy to make mistakes.
I am still an sql greenhorn and try to convert this script, building a running total as view in mysql:
DROP TABLE IF EXISTS `table_account`;
CREATE TABLE `table_account`
(
id int(11),
account int(11),
bdate DATE,
amount DECIMAL(10,2)
);
ALTER TABLE `table_account` ADD PRIMARY KEY(id);
INSERT INTO `table_account` VALUES (1, 1, '2014-01-01', 1.0);
INSERT INTO `table_account` VALUES (2, 1, '2014-01-02', 2.1);
INSERT INTO `table_account` VALUES (4, 1, '2014-01-02', 2.2);
INSERT INTO `table_account` VALUES (5, 1, '2014-01-02', 2.3);
INSERT INTO `table_account` VALUES (3, 1, '2014-01-03', 3.0);
INSERT INTO `table_account` VALUES (7, 1, '2014-01-04', 4.0);
INSERT INTO `table_account` VALUES (6, 1, '2014-01-06', 5.0);
INSERT INTO `table_account` VALUES (8, 1, '2014-01-07', 6.0);
SET #iruntot:=0.00;
SELECT
q1.account,
q1.bdate,
q1.amount,
(#iruntot := #iruntot + q1.amount) AS runningtotal
FROM
(SELECT
account AS account,
bdate AS bdate,
amount AS amount
FROM `table_account`
ORDER BY account ASC, bdate ASC) AS q1
This is much more faster than building a sum over the whole history on each line.
The problems I cannot solve are:
Set in view
Subquery in view
I think it might be posssible to use some kind of JOIN instead of "SET #iruntot:=0.00;"
and use two views to prevent the need of a subquery.
But I do know how.
Will be happy for any hints to try.
Regards,
Abraxas
MySQL doesn't allow subqueries in the from clause for a view. Nor does it allow variables. You can do this with a correlated subquery, though:
SELECT q.account, q.b_date, q.amount,
(SELECT SUM(q2.amount)
FROM myview1 q2
WHERE q2.account < q.account OR
q2.account = q.account and q2.date <= q.date
) as running total
FROM myview1 q;
Note that this assumes that the account/date column is unique -- no repeated dates for an account. Otherwise, the results will not be exactly the same.
Also, it seems a little strange that you are doing a running total across all accounts and dates. I might expect a running total within accounts, but this is how you formulated the query in the question.
I have to insert big amount of records in a table. It is not quite normalized, so most of the fields are repeated.
I know the proper command is:
INSERT INTO table_name (field1, field2, ..., field_n)
VALUES (value1, value2, ..., value_n),
...
(value1, value2, ..., value_n)
But I wonder whether it is possible to keep some of the values fixed and just indicate the different ones.
Let's say instead of
INSERT INTO table_name (shop, month, sale)
VALUES (1, 2, 23),
(1, 2, 28),
(1, 2, 29),
(1, 2, 30)
Having something like
INSERT INTO table_name (shop, month, sale)
VALUES (1, 2, 23), ... 28 / 29 / 30
If it is not possible I would create a procedure with a loop, feeding a string, etc. It would not be a big issue, but my point is to know if INSERT INTO has any particularity that allows doing this without procedures.
You can try something like the following:
INSERT INTO table_name (shop, month, sale)
SELECT * FROM
(SELECT 1 as shop, 2 as month) as sm,
(SELECT 23 as sale UNION ALL SELECT 28 UNION ALL SELECT 30) as sales;
You can use the default constraint which will add the default value when you do not specify that in the insert into statement. If you specify a value that value will be added.
Just set the default value for your column in your table
ALTER TABLE tblname ALTER columnName SET DEFAULT 'value'
Refer http://www.w3schools.com/sql/sql_default.asp
You can use a temporary table to insert the different values and then use insert ... select. I don't know if it will be a big saving for you:
CREATE TEMPORARY TABLE sale_temp (sale int);
INSERT sale_temp (sale) VALUES (23), (28), (29), (30);
INSERT INTO table_name (shop, month, sale)
SELECT 1, 2, sale
FROM sale_temp;
DROP TABLE sale_temp;