Sql decimal values not geting stored in temporary table - sql-server-2008

I am creating empty temporary table based on another table in my db and adding an extra column (PRICE) which i am trying to populate from query,
SELECT TOP 0 ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS RowNumber,
ID,
NULL AS PRICE
INTO #TMP_TABLE
FROM SQL_TABLE
when i fill this table as INSERT INTO #TMP_TABLE ... the value i am getting in PRICE column is either 0 or 1, but when i execute query seperately, i am getting decimal values (like0.0634).
how can i store decimal values in temp table above ? or is there any other way to create empty temp table ?

Use CREATE TABLE and define explicitly columns types:
CREATE TABLE #TMP_TABLE(RowNumber INT, ID <you_type>, Price <your_type>)
Default for NULL is INT, check:
SELECT x = NULL INTO #x;
EXEC tempdb..sp_columns '#x';
So your fraction are converted implicitly to INT
One good rule for future EXPLICIT IS ALWAYS BETTER THAN IMPLICIT

you either create the table with a create table statement:
create table #TMP_TABLE
( RowNumber int
, ID <whatever datatype>
, PRICE numeric(10,2)
);
or if you insist on select into declare the datatype :
SELECT TOP 0 ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS RowNumber,
ID,
cast(NULL as numeric(10,2)) AS PRICE
INTO #TMP_TABLE
FROM SQL_TABLE

Related

SQL Using CASE with criteria stored as a value in another table

I'm hoping that I'm overlooking something really simple with my issue. I have a fee calculation query that I need to write that utilizes rules in many tables to calculate. One of the tables defines the conditions for which a particular fee will be applicable. I was hoping to avoid dynamic SQL but if it will be required please note that I have a few CTEs that are being used in the master procedure.
I've simplified the stored procedure to the following which illustrates the problem well. I need to have the contents of the [Formula] applied as the Boolean expression in the case statement but I continue to receive the error:
An expression of non-boolean type specified in a context where a condition is expected, near 'THEN'
If you replace the field Formula with the actual contents it works as desired.
CREATE TABLE #FeeRule
(
FeeRuleID INT IDENTITY,
FeeName NVARCHAR(50),
FeeRate DECIMAL(10,2)
)
INSERT INTO #FeeRule
SELECT 'FlatFee', 450.00
CREATE TABLE #FeeCondition
(
ConditionID INT IDENTITY,
FeeRuleID INT,
Formula NVARCHAR(255)
)
INSERT INTO #FeeCondition
SELECT 1, 'StockType = 1'
CREATE TABLE #Accounts
(
ID INT IDENTITY,
AcctName NVARCHAR(200),
StockType INT
)
INSERT INTO #Accounts
SELECT 'Account One', 0 UNION ALL
SELECT 'Account Two', 1
SELECT
AcctName,
Fee = CASE
WHEN Formula IS NULL
THEN FeeRate
ELSE
CASE WHEN Formula -- StockType = 1 --
THEN FeeRate
ELSE 0
END
END
FROM
#Accounts A
JOIN
#FeeRule B ON 1 = 1
LEFT JOIN
#FeeCondition C ON C.FeeRuleID = B.FeeRuleID
DROP TABLE #FeeRule
DROP TABLE #FeeCondition
DROP TABLE #Accounts

insert a new record into a mysql table with one of the values incremented by 1

I've got the following table:
productId price
1 price_value1
2 price_value2
3 price_value3
I would like to insert a new product into the table and assign it a new productId. In this case its value equals to 4.
So I want my new table to look like so:
productId price
1 price_value1
2 price_value2
3 price_value3
4 price_value4
So as far as I understand, in order to do that I have to somehow retrieve the max value of productId and insert it using INSERT INTO mytable VALUES (productId + 1, price_value4).
But how do I find out the maximum value of productId?
I tried INSERT INTO mytable VALUES (SELECT MAX(productId) + 1 FROM mytable, price_value4) but it didn't work.
This should Work:
Select the max(productID) and price_value4 as a columns from mytable and insert the result.
INSERT INTO mytable (SELECT MAX(productId) + 1, 'price_value4' FROM mytable);
However, if you are not going to jump some number you can just add an auto increment id key to product_id and then you will have only to insert the price, the product ID will be incremented automatically..
This will do so :
ALTER TABLE mytable
MODIFY COLUMN `productId` INT(10) UNSIGNED PRIMARY KEY AUTO_INCREMENT;
you can change INT(10) with the INT(5) for example depanding on the size you want to give to your productId column
EDIT :
In return to the OP question in comments why his solution wouldn't work
Some suggetions says you have to make the SELECT statment in insert always between parenthesis
INSERT INTO mytable VALUES ( (SELECT MAX(ID)+1 FROM mytable) , price_value4)
.. In my Case it Return
(1093): You can't specify target table
'mytable' for update in FROM clause
AND HERE IS WHY (Quoting From the documentation)
When selecting from and inserting into the same table, MySQL creates
an internal temporary table to hold the rows from the SELECT and then
inserts those rows into the target table. However, you cannot use
INSERT INTO t ... SELECT ... FROM t when t is a TEMPORARY table,
because TEMPORARY tables cannot be referred to twice in the same
statement
BUT there is away to overcome by using a query instead of the table itself in the FROM, which has the effect of copying the requested table values instead of referencing the one that you are updating..
INSERT INTO mytable VALUES (
(SELECT MAX(ID)+1 FROM (SELECT * FROM mytable ) as mytmp ),
'price_value4');
OR (Quoting From the documentation)
To avoid ambiguous column reference problems when the SELECT and the
INSERT refer to the same table, provide a unique alias for each table
used in the SELECT part, and qualify column names in that part with
the appropriate alias.
INSERT INTO mytable Values ( (SELECT MAX(ID)+1 FROM mytable as mytmp) , 'price_value4')
This is a duplicate question. In order to take advantage of the auto-incrementing capability of the column, do not supply a value for that column when inserting rows.
A simple syntax to create table
CREATE TABLE Product (
productId MEDIUMINT NOT NULL AUTO_INCREMENT,
price INT NOT NULL,
PRIMARY KEY (productid)
);
While inserting supplied default or leave column as blank or supplied value as NULL. Take a look at below code snippet.
INSERT INTO Product (price) VALUES
('10'),('20'),('4'),
('30');
refer this link

SQL insert with empty value for the id

How do I insert a sql row into a new table where it meets criteria but resets the id value. In other words, copy the row, but reset the id value.
This is my current sql
INSERT INTO followers_lost SELECT * FROM followers WHERE pk = $pk
I tried to SET id=null and VALUE (0), but both don't work.
All you have to do since you want all the columns except the identity is specify all the non-identity columns on the insert:
INSERT INTO [followers_lost] ([Column1],[column2]...{but not the identity
column})
SELECT [Column1],[column2]...{but not the identity column} FROM followers WHERE
pk = $pk
You can create the column and then update it:
SET #new_id=0;
UPDATE your_table
SET id = #new_id := #new_id + 1
where id = 0
OK based on your comment I think you are trying to take all or some of the fields from Followers except the PK and put them into Followers_Lost where they equal a certain PK. If you want multiple PK's you would need to change the where clause to an IN statement instead of an equal and adjust your values accordingly.
CREATE TABLE dbo.UAT_Followers_Lost (PK INT IDENTITY(1,1),DATA VARCHAR(50) )
CREATE TABLE dbo.UAT_Followers (PK INT IDENTITY(1,1),DATA VARCHAR(50) )
INSERT INTO dbo.UAT_Followers
(DATA)
SELECT 'Jan'
UNION ALL
SELECT 'Feb'
UNION ALL
SELECT 'Mar'
DECLARE #PK INT
SET #PK = 1
INSERT INTO dbo.UAT_Followers_Lost
(Data)
SELECT Data
FROM dbo.UAT_Followers
WHERE PK = #PK

SQL - CURDATE() + 4 random digits (2013-10-02-0001)

create table Table1(
DateIdentify CHAR(15),
primary key(DateIdentify)
);
Insert into Table1 (DateIdentify) VALUES('?');
How I want the 'DateIdentify' to look: (20131002-0001) with 0001 being some sort of an auto incrementer that starts at 0001 and goes up every insert and 20131002 coming from CURDATE(), so adding CURDATE() + 4 digits. I'm wondering if this is possible? If so, could anyone please point me in the right direction?
EDIT:
CREATE TABLE Table1(
IdTable1 int auto_increment NOT NULL,
Date1 datetime,
);
You have to separate your datetime and the auto increment field.
Create your table like this using an auto-increment int field, and your datetime.
For example:
CREATE TABLE Table1(
IdTable1 int PRIMARY KEY IDENTITY(1,1) NOT NULL,
Date datetime
)
Then, you don't have to insert anything in IdTable1 because of it is auto-incremented thanks to keyword IDENTITY (SQL do the auto-increment for you)
NOTE : I wrote this for SQLServer, if you use another database, the code can change a little bit.
Which one do you use ?
EDIT :
You can also do some insert like this :
INSERT INTO Table1
(
Date
)
VALUES
(
'2013-10-02'
)
In case a solution is required as, having only one column with values in desired format you can create a function as:
create function dbo.fn_GetDateIdentify ()
returns varchar(15)
as
begin
declare #DateIdentify varchar(15);
select #DateIdentify =
(select convert (varchar(8),GETDATE (),112) +
'-' +
right ('00000' + cast (
(
(
case when Not exists (select ROW_NUMBER() over( order by (select 1)) from Table1 ) then 1
else (select top 1 ROW_NUMBER() over( order by (select 1)) as currentRownumber from Table1 order by currentRownumber desc) + 1
end
)
)
as varchar(4))
,4));
return #DateIdentify;
end
go;
and then use the function in insert statement as :
insert into Table1 (DateIdentify)
select dbo.fn_GetDateIdentify();
Hope this helps!

Dynamically pick field to select data from

Say I have a table with three columns primaryNum, secondaryNum, chosenNum. primarynum and secondaryNum are both number values but chosenNum's value can either be "primaryNum", "secondaryNum", or "both".
The chosenNum field is a column that gives me the option to search for a number in a particular field.
For example: I might want to try to find all rows with the value 10 in the column that is stored in chosenNum. If the value of chosenNum is "both" then the row would be returned if either column (primaryNum, secondaryNum) had a value of 10.
What might my select statement look like?
It might be a better scenario if I say I would like to do a select statement like:
SELECT * FROM aTable WHERE (SELECT bVal FROM bTable WHERE aVal = #varField ) = 0;
Where #varField is the value of the value in the field with the label stored in chosenNum or either field if chosenNum = "both"
This would result in me getting back rows with id 1,2,3,4,6,7,14,15,16,19,20,21,23,24,27
Table A: Create
CREATE TABLE `test`.`aTable` (
`id` INT NOT NULL AUTO_INCREMENT ,
`primaryNum` INT NULL ,
`secondaryNum` INT NULL ,
`chosenNum` CHAR(12) NULL ,
PRIMARY KEY (`id`) );
Table B: Create
CREATE TABLE `test`.`bTable` (
`aVal` INT NULL ,
`bVal` INT NULL );
Table A: Data
INSERT INTO test.aTable VALUES (1,8,7,'secondaryNum'),(2,2,9,'secondaryNum'),(3,7,9,'both'),(4,5,1,'both'),(5,10,3,'secondaryNum'),(6,10,6,'both'),(7,7,8,'both'),(8,10,2,'primaryNum'),(9,2,1,'secondaryNum'),(10,7,2,'secondaryNum'),(11,2,2,'secondaryNum'),(12,5,1,'secondaryNum'),(13,1,6,'primaryNum'),(14,6,6,'both'),(15,4,9,'both'),(16,9,7,'primaryNum'),(17,8,3,'secondaryNum'),(18,10,7,'primaryNum'),(19,8,5,'secondaryNum'),(20,1,7,'both'),(21,7,9,'both'),(22,8,3,'primaryNum'),(23,6,2,'primaryNum'),(24,5,7,'both'),(25,2,1,'both'),(26,5,2,'secondaryNum'),(27,7,8,'primaryNum');
Table B: Data
INSERT INTO test.bTable VALUES (1,1),(2,1),(3,1),(4,1),(5,0),(6,0),(7,0),(8,1),(9,0),(10,1);
You can do something like this:
select *
from MyTable
where (chosenNum in ('both', 'primaryNum') and primaryNum = 10)
or (chosenNum in ('both', 'secondaryNum') and secondaryNum = 10)