Trying to Multiply a Case Statement to a Count - sql

DECLARE #StartDate datetimeoffset,
#EndDate datetimeoffset
SET #StartDate = '2022-03-01 00:00:00.000 +07:00'
SET #EndDate = '2022-03-06 23:59:59.000 +07:00'
SELECT
Records.RecordID,
CONVERT(VARCHAR(10),Records.RecDate AT TIME ZONE 'SE Asia Standard Time',104) AS RecTime,
LocationStr, LocationName,
CONCAT(FirstName,' ',LastName) AS Username ,ProductCodeName,
CASE
WHEN AssetTypeName LIKE '%LTR'
THEN LEFT(AssetTypeName, LEN(AssetTypeName) - 3)
ELSE LEFT(AssetTypeName, LEN(AssetTypeName) - 2)
END * COUNT (ProductCodeName) AS 'SumProduct'
FROM
opendata.records
INNER JOIN
opendata.RecAssets ON Records.RecordId = RecAssets.RecordId
WHERE
(Records.ActionName = 'Fill')
AND (IsDeleted = '0')
AND (Records.RecDate BETWEEN #StartDate and #EndDate)
AND (LocationStr = '3031')
GROUP BY
Records.RecordId, Records.RecDate, LocationStr, LocationName,
CONCAT(FirstName,' ', LastName), ProductCodeName, AssetTypeName
ORDER BY
LocationStr ASC, RecTime ASC, ProductCodeName ASC
Tried to multiply the last to column on my Select statement but failed to do so. I get an error
Conversion failed when converting the ****** value '******' to data type ******.
Furthermore, I tried to convert the case statement to an int but also failed. How can I directly multiply it?

I'm guessing that you're using sql server seeing as it's not oracle and len() is not supported in mySQL or Postgres. You're code calls for an implicit conversion from a numerical value in a char type to a number, for example '123' to 123.
In the following example this doesn't present a problem the first time, but the second time there is a letter in the char value which cannot be converted and throws an error.
I am therefore thinking that you have values of AssetTypeName where there are letters other than in the last 2 characters for non-LTR values of elsewhere in the string for those ending in LTR.
create table test(
AssetTypeName varchar(10),
ProductCodeName int);
insert into test values
('123LTR',1),
('123LTR',1),
('123AB',1);
GO
3 rows affected
select
AssetTypeName,
CASE
WHEN AssetTypeName LIKE '%LTR'
THEN LEFT(AssetTypeName, LEN(AssetTypeName) - 3)
ELSE LEFT(AssetTypeName, LEN(AssetTypeName) - 2)
END * COUNT (ProductCodeName) AS 'SumProduct'
from test
group by AssetTypeName;
GO
AssetTypeName | SumProduct
:------------ | ---------:
123AB | 123
123LTR | 246
insert into test values ('123ABC',1);
GO
1 rows affected
select
AssetTypeName,
CASE
WHEN AssetTypeName LIKE '%LTR'
THEN LEFT(AssetTypeName, LEN(AssetTypeName) - 3)
ELSE LEFT(AssetTypeName, LEN(AssetTypeName) - 2)
END * COUNT (ProductCodeName) AS 'SumProduct'
from test
group by AssetTypeName;
GO
Msg 245 Level 16 State 1 Line 1
Conversion failed when converting the varchar value '123A' to data type int.
db<>fiddle here

Related

Leading 0 on int Column problem SQL Server

I have an issue where I am trying to add a leading 0 to run an output.
SELECT
CASE
WHEN LEN(t.trans_time) = 5
THEN CONCAT(0, [trans_time])
ELSE T.[trans_time]
END AS [TransactionTime]
,RIGHT(CONCAT(0,trans_time),6) AS trans_time
,LEN(T.trans_Time)
,t.trans_time
Why does the case statement not return the leading 0 whereas using:
,RIGHT(CONCAT(0,trans_time),6) AS trans_time
Works no problem.
Case expression return only one type, whereas concat() would return different type & i am assuming trans_time has INT type.
So, you would need to do type conversations :
SELECT (CASE WHEN LEN(t.trans_time) = 5
THEN CONCAT(0, [trans_time])
ELSE CAST(T.[trans_time] AS VARCHAR(255))
END) AS [TransactionTime],
. . .
Another way to do this is to use the format function, wich is available from sql server 2012.
It not only makes the code more readable but will also perform better.
declare #t table (id int)
insert into #t values (90113), (90204), (90207), (90235), (90302), (90318), (90324)
select format(id, '000000') as TransactionTime from #t
this will return
TransactionTime
---------------
090113
090204
090207
090235
090302
090318
090324

Mathematical Function within Sql Case Statement

I am trying to come up with a sql statement which converts the odometer if stored in km to miles. If the odometer is stored in miles, it leaves as it is.
After the conversion, it then needs to check for Search paramters i.e Mileage.
The steps I have taken is using the Case Statement.
Here is my snippet of the select statement that I am using currently:
DECLARE
#Mileage NVARCHAR(75) = NULL,
#IsMiles BIT = 1,
#Converted NVARCHAR(75) = NULL
SELECT [Id],Odometer,IsMiles,
CASE IsMiles when 0 THEN OdometerValue * 0.62137
else Odometer end
FROM [dbo].[Vehicle]
where IsMiles = 0
Is there anyway to pass the Result of the case statement to ConvertedOdometer. I want to use that value to evaluate against the search Mileage parameters.
Something like this with this condition:
(ConvertedOdometer >=0 AND ConvertedOdometer <= #Mileage)
I am new to Case statement so have used these guides:
StackOverflow
Sql School
Some Blog
Perhaps something like this ...
DECLARE
#Mileage NVARCHAR(75) = NULL,
#IsMiles BIT = 1,
#Converted NVARCHAR(75) = NULL
select a.* from
(SELECT [Id],Odometer,IsMiles,
CASE when IsMiles=0 THEN OdometerValue * 0.62137 else Odometer end as ConvertedOdometer
FROM [dbo].[Vehicle]
where IsMiles = 0)a
where a.ConvertedOdometer >=0 AND
a.ConvertedOdometer <= #Mileage

SQL Server 2012--Conversion Failed when converting date and/or time from character string

I've been through all the thread here on this topic and tried all the suggestions, but nothing seems to get rid of this error. Can someone please tell me what's wrong with my sql that is causing this error to be generated? The table I'm trying to insert to is all nvarchar except for the date fields and a couple of integer fields which I'm doing casts on to make sure the types are correct.
SQL is as follows.
insert into [dell.des.SkuOrder] (LineitemKey,IdForSaba,StatusMessage,OrderNumber,OrderDateTime,SalesrepName,OrderTotal,OrderedSkuNumber,
QuantityOrdered, SkuType,DetailSequenceNumber, PartNumber,CustomerNumber,PartQuantity,CustomerNameP,Address1P,Address2P,CityP,StateCode,
FirstNameP,LastNameP,Email,PhoneNumber,CustomerNumberB,CustomerNameB,Address1B,CityB,StateCodeB,ContactNameB,
FirstNameB, LastNameB,EmailB,PhoneNumberb,SabaCurrency,SabaLocale,SabaOrg,StatusDateTime,
SabaRegion, ExpirationDate,TransactionValue,SabaOrderNumber)
SELECT Distinct
SKU_TYPE as SkuType,
PART_ID as PartNumber,
(CUSTOM1 + ' ' + CUSTOM2) as ContactNameB,
headers.EXT_ID1 as OrderNumber,
CUSTOM1 as FirstNameB,
CUSTOM0 as CustomerNameP,
CURRENCY_ID as SabaCurrency,
CUSTOM1 as FirstNameP,
CUSTOM0 as CustomerNameB,
CASE WHEN ISDATE(EXPIRATION_DATE)=1 then CAST( EXPIRATION_DATE as datetime ) else null end as ExpirationDate,
CUSTOM2 as LastNameP,
CASE WHEN ISNUMERIC (AVL_QTY)=1 then CAST (AVL_QTY as int) else null end as QuantityOrdered,
CUSTOM7 as PhoneNumber,
CUSTOM2 as LastNameB,
CUSTOM3 as Address1P,
CONTACT_EMAIL as Email,
ORG as CustomerNumber,
CUSTOM7 as PhoneNumberB,
CUSTOM3 as Address1B,
CASE WHEN ISNUMERIC(PURCH_QTY)=1 then CAST (PURCH_QTY as int) else null end as PartQuantity,
DetailSequenceNuber=1,
CUSTOM4 as Address2P,
SKU as OrderedSkuNumber,
CONTACT_EMAIL as EmailB,
CUSTOM6 as StateCodeB,
CUSTOM4 as Address2B,
CUSTOM5 as CityP,
TransactionValue=0,
ORG as SabaOrg,
CUSTOM9 as SalesrepName,
LineitemKey=(headers.EXT_ID1 + '_'+ SKU + '_1'),
CASE when ISDATE( ORD_CREATION_DATE)=1 then CAST(ORD_CREATION_DATE as datetime) else null END as OrderDateTime,
CUSTOM6 as StateCode,
ORG as CustomerNumberB,
StatusMessage = 'Imported ST Order - OPEN',
CASE WHEN ISDATE(headers.UPDATED_ON)=1 then CAST(headers.UPDATED_ON as datetime ) else null end as StatusDateTime,
CUSTOM5 as CityB,
CUSTOM8 as OrderTotal,
headers.EXT_ID1 as IdForSaba,
items.SKU_ORDER_NO as SabaOrderNumber,
locale = CASE
WHEN LOCALE_NAME = 'English' then 'local000000000000001'
WHEN LOCALE_NAME = 'Deutsh (German)' then 'local000000000000001'
WHEN LOCALE_NAME = 'English (United Kingdom)' then 'local00000000000008'
WHEN LOCALE_NAME = 'Nederlands (Dutch)' then 'local000000000000007'
WHEN LOCALE_NAME = 'Español (Latin America)' then 'local000000000000006'
WHEN LOCALE_NAME = '繁體中文 (Chinese Traditional)' then 'local000000000000025'
WHEN LOCALE_NAME ='日本語 (Japanese)' then 'local0000000000000011'
WHEN LOCALE_NAME ='简体中文 (Chinese Simplified)' then 'local000000000000005'
WHEN LOCALE_NAME ='한국어 (Korean)' then 'local000000000000024'
WHEN LOCALE_NAME ='Português (Brasil)' then 'local000000000000014'
WHEN LOCALE_NAME ='Français canadien (French Canadian)' then 'local000000000000012'
END
FROM [dbo].[STOrderHeaders] headers
inner join [dbo].[STOrderItems] items on headers.EXT_ID1= items.EXT_ID1
I've spent the past two days working on this trying everything. I know the casts work because the select portion of the query works just fine. I'm not sure if it has anything to do with the fact that the data was imported as UTF-8 in to my two staging tables, but the destination table also contains UTF-8 data.
Any help would be greatly appreciated!
Insert - 5th column is OrderDateTime
Select- 5th column is FirstNameB
Are you trying to insert wrong value into the DateTime Column ?
Thank you! I had the columns out of order and sorting that out got rid of the conversion error.

"Insert Into Select" writing to table but contains sub-query reading from same table

I am adding records into my table "SampleTestLimits" using an "Insert Into Select", but which also has a sub-query reading from the same table to perform a count for me.
I don't think the sub-query is seeing the earlier records added by my "Insert Into Select". It's the same for Oracle and SQL Server. The code for SQL Server is shown below (my sub-query begins with "SELECT COALESCE...").
I have another stored procedure which does work in a similar situation.
Would appreciate it if anybody could tell if what I'm doing is a no no.
ALTER PROCEDURE [dbo].[CreateSampleTestLimits]
#SampleCode as NVARCHAR(80),
#TestPosition as smallint,
#TestCode NVARCHAR(20),
#TestVersion smallint,
#EnterDate as integer,
#EnterTime as smallint,
#EnterUser as NVARCHAR(50)
AS
BEGIN
INSERT INTO SampleTestLimits
([AuditNumber]
,[LimitNumber]
,[ComponentRow]
,[ComponentColumn]
,[ComponentName]
,[TestPosition]
,[SampleCode]
,[AuditFlag]
,[LimitSource]
,[LimitType]
,[UpperLimitEntered]
,[UpperLimitValue]
,[LowerLimitEntered]
,[LowerLimitValue]
,[LimitTextColour]
,[LimitPattern]
,[LimitForeColour]
,[LimitBackColour]
,[CreatedDate]
,[CreatedTime]
,[CreatedUser]
,[LimitText]
,[FilterName]
,[deleted]
,IsRuleBased)
SELECT 1 --starting auditnumber
,(SELECT COALESCE(MAX(LimitNumber), 0) + 1 AS NextLimitNumber FROM SampleTestLimits WHERE SampleCode=#SampleCode AND TestPosition=#TestPosition AND ComponentRow=1 AND ComponentColumn=1 AND AuditFlag=0) -- TFS bug# 3952: Calculate next limit number.
,ComponentRow
,ComponentColumn
,(select ComponentName from TestComponents TC where TC.TestCode=#TestCode and TC.ComponentColumn=TestLimits.ComponentColumn and TC.ComponentRow = TestLimits.ComponentRow and TC.AuditNumber=TestLimits.AuditNumber)
,#TestPosition
,#SampleCode
,0 --auditflag
,1 --limitsource = test
,[LimitType]
,[UpperLimitEntered]
,[UpperLimitValue]
,[LowerLimitEntered]
,[LowerLimitValue]
,[LimitTextColour]
,[LimitPattern]
,[LimitForeColour]
,[LimitBackColour]
,#EnterDate
,#EnterTime
,#EnterUser
,[LimitText]
,[FilterName]
,0 --deleted
,0 --rule based
FROM TestLimits join Tests on Tests.TestCode=TestLimits.TestCode and Tests.AuditNumber= TestLimits.AuditNumber WHERE Tests.TestCode=#TestCode and Tests.auditnumber=#TestVersion and ([TestLimits].FilterString is null or DATALENGTH([TestLimits].FilterString)=0)
END
Assuming that I understand your logic correctly (ie. that you want the nextlimitnumber to increase by 1 for each row being added), in Oracle, I'd do it by using the analytic function row_number() to work out what number to add to the previous max value, something like:
INSERT INTO sampletestlimits (auditnumber,
limitnumber,
componentrow,
componentcolumn,
componentname,
testposition,
samplecode,
auditflag,
limitsource,
limittype,
upperlimitentered,
upperlimitvalue,
lowerlimitentered,
lowerlimitvalue,
limittextcolour,
limitpattern,
limitforecolour,
limitbackcolour,
createddate,
createdtime,
createduser,
limittext,
filtername,
deleted,
isrulebased)
SELECT 1, --starting auditnumber
(SELECT COALESCE (MAX (limitnumber), 0) + 1 AS nextlimitnumber
FROM sampletestlimits
WHERE samplecode = p_samplecode
AND testposition = p_testposition
AND componentrow = 1
AND componentcolumn = 1
AND auditflag = 0)
+ row_number() over (partition by testposition, componentrow, componentcolumn, auditflag) as nextlimitnumber, -- TFS bug# 3952: Calculate next limit number.
componentrow,
componentcolumn,
(SELECT componentname
FROM testcomponents tc
WHERE tc.testcode = p_testcode
AND tc.componentcolumn = testlimits.componentcolumn
AND tc.componentrow = testlimits.componentrow
AND tc.auditnumber = testlimits.auditnumber),
p_testposition,
p_samplecode,
0, --auditflag
1, --limitsource = test
limittype,
upperlimitentered,
upperlimitvalue,
lowerlimitentered,
lowerlimitvalue,
limittextcolour,
limitpattern,
limitforecolour,
limitbackcolour,
p_enterdate,
p_entertime,
p_enteruser,
limittext,
filtername,
0, --deleted
0 --rule based
FROM testlimits
JOIN tests
ON tests.testcode = testlimits.testcode
AND tests.auditnumber = testlimits.auditnumber
WHERE tests.testcode = p_testcode
AND tests.auditnumber = p_testversion
AND ( testlimits.filterstring IS NULL
OR datalength (testlimits.filterstring) = 0);
I had to guess at what the partition by clause would need to contain - adjust that as necessary for your requirements.

How can I structure an IF statement inside of a SELECT statement?

I'm hoping that what I have paints a clear enough picture of what I am trying to accomplish:
SELECT [Date]
,[ChargeCode]
,[ChargeDescription]
,[HHY_Qty]
,[PatPrice]
, IF ISNUMERIC(HHY_Qty) AND ISNUMERIC(PatPrice)
BEGIN
CAST(HHY_Qty AS INT) * CAST(PatPrice AS INT) AS ExtAmt
END
ELSE
0 AS ExtAmt
END
FROM [dbo].[ChargeDetails]
WHERE PatientNumber = '1271'
HHY_Qty and PatPrice are both VARCHAR types in a MSSQL database. They were created with a BULK INSERT from a very very very dirty CSV from an AS400 export. Here, I am trying to do some multiplication IF the fields are numeric values, otherwise ExtAmt should be 0. Is that possible? If not,, is there a workaround?
Use a CASE statement:
CASE WHEN ISNUMERIC(HHY_Qty) = 1 AND ISNUMERIC(PatPrice) = 1 THEN CAST(HHY_Qty AS INT) * CAST(PatPrice AS INT) ELSE 0 END AS ExtAmt