Incorrect Syntax Error in SQL Server - sql-server-2008

UPDATE SHIPPER_LINE
SET ACT_FREIGHT =
convert(decimal(10,2),
(CASE
WHEN CAST(RATE AS FLOAT) >= 0 AND CAST(RATE AS FLOAT) <= 105 THEN
CAST(RATE AS FLOAT) * 1.2
WHEN CAST(RATE AS FLOAT) >= 105.01 AND CAST(RATE AS FLOAT) <= 145.99 THEN
CAST(RATE AS FLOAT) = 146
WHEN CAST(RATE AS FLOAT) >= 146 THEN CAST(RATE AS FLOAT) * 1.06
ELSE CAST(Rate AS Float)
END))
The above is part of an existing trigger I'm editing. I'm getting a syntax error under the '=' sign on the 'Cast(rate as float) = 146' section. What is the proper syntax to make the 'Rate' equal 146 when within the specified range?

Are you trying to update RATE or use the value 146
You cant do the first here, the second just return 146
UPDATE SHIPPER_LINE
SET ACT_FREIGHT = convert(DECIMAL(10, 2), (
CASE
WHEN CAST(RATE AS FLOAT) >= 0
AND CAST(RATE AS FLOAT) <= 105
THEN CAST(RATE AS FLOAT) * 1.2
WHEN CAST(RATE AS FLOAT) >= 105.01
AND CAST(RATE AS FLOAT) <= 145.99
THEN 146 -- just return the value
WHEN CAST(RATE AS FLOAT) >= 146
THEN CAST(RATE AS FLOAT) * 1.06
ELSE CAST(Rate AS FLOAT)
END
))

Related

Error Code: 1292 Truncated incorrect INTEGER value: '358.93601676744487'

Hei, i've some problems according to my query can anyone help me. Here di SQL script :
The condition was :
The datatype (in table) several in varchar, several in integer, several in double.
And what i want is to fullfill this result in one click.
INSERT INTO fix_table
SELECT * , numerator/denumerator AS result
FROM (
SELECT * ,
(field_1+field_2+field_3) AS numerator,
(weight_1 + weight_2 + weight_3) AS denumerator
FROM (
SELECT * ,
CASE
WHEN `download_throughput_kbps` = "NULL" THEN 0
WHEN CAST(`download_throughput_kbps` AS UNSIGNED) >= 5000 THEN 100*5
WHEN CAST(`download_throughput_kbps` AS UNSIGNED) >= 3000 THEN 80*5
WHEN CAST(`download_throughput_kbps` AS UNSIGNED) >= 1500 THEN 60*5
WHEN CAST(`download_throughput_kbps` AS UNSIGNED) >= 700 THEN 40*5
WHEN CAST(`download_throughput_kbps` AS UNSIGNED) >= 200 THEN 20*5
WHEN CAST(`download_throughput_kbps` AS UNSIGNED) < 200 THEN 0
ELSE 998
END AS field_1,
CASE
WHEN `upload_throughput_kbps` = "NULL" THEN 0
WHEN CAST(`upload_throughput_kbps` AS UNSIGNED) >= 2941 THEN 100*5
WHEN CAST(`upload_throughput_kbps` AS UNSIGNED) >= 252 THEN 80*5
WHEN CAST(`upload_throughput_kbps` AS UNSIGNED) >= 39 THEN 60*5
WHEN CAST(`upload_throughput_kbps` AS UNSIGNED) >= 16 THEN 40*5
WHEN CAST(`upload_throughput_kbps` AS UNSIGNED) >= 3 THEN 20*5
WHEN CAST(`upload_throughput_kbps` AS UNSIGNED) < 3 THEN 0
ELSE 998
END AS field_2,
CASE
WHEN `response_delay_ms` = "NULL" THEN 0
WHEN CAST(`response_delay_ms` AS UNSIGNED) < 190 THEN 100*5
WHEN CAST(`response_delay_ms` AS UNSIGNED) < 270 THEN 80*5
WHEN CAST(`response_delay_ms` AS UNSIGNED) < 420 THEN 60*5
WHEN CAST(`response_delay_ms` AS UNSIGNED) < 800 THEN 40*5
WHEN CAST(`response_delay_ms` AS UNSIGNED) < 2460 THEN 20*5
WHEN CAST(`response_delay_ms` AS UNSIGNED) >= 2460 THEN 0
ELSE 998
END AS field_3
CASE
WHEN `download_throughput_kbps` = "NULL" THEN 0
ELSE 5
END AS weight_1,
CASE
WHEN `upload_throughput_kbps` = "NULL" THEN 0
ELSE 5
END AS weight_2,
CASE
WHEN `response_delay_ms` = "NULL" THEN 0
ELSE 5
END AS weight_3
FROM sometables
WHERE `datehourss` = "2020-10-06%"
) AS new_table
) AS new_table_2;
sorry still new bie

SQL How to correctly use the where operator in my query?

There is a request for 15 minute intervals in the interval from 09.00 to 18.00 hours.
SELECT t.event_date,
case
when TIME_TO_SEC(t.event_date) > inter.begin AND TIME_TO_SEC(t.event_date) < inter.end
then floor((TIME_TO_SEC(t.event_date) - inter.begin) / inter.width)
when TIME_TO_SEC(t.event_date) <= inter.begin
then 0
when TIME_TO_SEC(t.event_date) >= inter.end
then floor((inter.end - inter.begin) / inter.width)
else null
end as full_interval_number
FROM table t,
(select TIME_TO_SEC('09:00:00') as begin,
TIME_TO_SEC('18:00:00') as end,
TIME_TO_SEC('00:15:00') as width
) inter
How to use WHERE to exclude temporary intrevalues №0, 3, 7, 15 or intrevalues from 09.00 to 10.00 hours?
Something like this:
where
TIME_TO_SEC(event_date) < TIME_TO_SEC('09:00:00')
and TIME_TO_SEC(event_date) > TIME_TO_SEC('10:00:00')
or:
where
full_interval_number not in (0, 3, 7, 15)
Is this what you want? The first part is the general limit for 9-18 and the second part is the specific requirement to exclude values between 9-10
where TIME_TO_SEC(event_date) between TIME_TO_SEC('09:00:00') and TIME_TO_SEC('18:00:00')
and not (TIME_TO_SEC(event_date) between TIME_TO_SEC('09:00:00') and TIME_TO_SEC('10:00:00'))
Full query
SELECT t.event_date,
case
when TIME_TO_SEC(t.event_date) > inter.begin AND TIME_TO_SEC(t.event_date) < inter.end
then floor((TIME_TO_SEC(t.event_date) - inter.begin) / inter.width)
when TIME_TO_SEC(t.event_date) <= inter.begin
then 0
when TIME_TO_SEC(t.event_date) >= inter.end
then floor((inter.end - inter.begin) / inter.width)
else null
end as full_interval_number
FROM table t,
(select TIME_TO_SEC('09:00:00') as begin,
TIME_TO_SEC('18:00:00') as end,
TIME_TO_SEC('00:15:00') as width
) inter
where TIME_TO_SEC(event_date) between TIME_TO_SEC('09:00:00') and TIME_TO_SEC('18:00:00')
and not (TIME_TO_SEC(event_date) between TIME_TO_SEC('09:00:00') and TIME_TO_SEC('10:00:00'))

Using ISNULL in where clause

DECLARE #use10percent INT
SELECT
#use10percent = COUNT(*)
FROM
[dbo].[CUSTOMER_ORDER] o
INNER JOIN
[dbo].[CUSTOMER] c ON c.ID = o.CUSTOMER_ID
INNER JOIN
[dbo].[CUST_ADDRESS] ca ON ca.CUSTOMER_ID = o.CUSTOMER_ID
AND ca.ADDR_NO = o.[SHIP_TO_ADDR_NO]
WHERE
o.[ID] = #CUST_ORDER_ID
AND (isnull(ca.STATE, c.STATE) IN ('AB','BC','MB','MT','NB','NS','ON','PQ','QC','SK','TX','NY'))
/**/
UPDATE SHIPPER_LINE
SET ACT_FREIGHT = CONVERT(DECIMAL(10, 2),
(CASE
WHEN CAST(ShipWeight AS Float) >= 400
THEN CAST(Rate AS Float) * 1.06
WHEN CAST(ShipWeight AS Float) < 400
THEN CASE
WHEN #use10percent = 0
THEN CAST(Rate AS Float) * 1.20
ELSE CAST(Rate AS Float) * 1.10 --New rate for Canada, TX, and NY
END
ELSE CAST(Rate AS Float)
END))
The goal of this trigger is to add 10% to the freight charge when the weight is under 400lbs and the destination state is NY, TX, or all of Canada. It works if the customer uses a drop ship address (ca.state) and I get a 10% increase. But if the customer is the buyer and destination, the (ca.state) is null and the (c.state) needs to be used. The code above adds the full 20% if the (ca.state) is null and the (c.state) is NY, TX, or Canada.
How can I fix the where clause to filter correctly?
The WHERE part about STATE check seems to be good:
isnull(ca.STATE, c.STATE) IN ('AB','BC','MB','MT','NB','NS','ON','PQ','QC','SK','TX','NY')
If it adds 20% it means that #use10percent is zero, are you sure about JOIN and data into the tables? Have you attempted removing COUNT and watching about SELECT result?

SUM from two tables, sort by country and publisher

I have two different sales tables and i want to SUM the quantity and FEEs for storeX and storeY from book_sales(isa), with quantity from all sales in the financial_report(xo). Im having trouble with both, and i dont know which JOIN i should use. The quantity calculation does not give any results and the fee calculation gives a number that is way to high. What is wrong here?
Please check my procedure if you have time:
ALTER PROCEDURE [dbo].[Report] #startDate VARCHAR(10),
#endDate VARCHAR(10)
AS
SELECT BB.name AS 'Publisher',
Sum(CASE
WHEN isa.report_source = 'storeX'
or isa.report_source = 'storeY' THEN
isa.quantity * xo.quantity
END) AS 'Total quantity',
Sum(CASE
WHEN isa.sales_price > 69
AND isa.report_source = 'storeX' THEN
6 * 1.25 * isa.quantity
WHEN isa.sales_price <= 69
AND isa.report_source = 'storeX' THEN
3 * 1.25 * isa.quantity
WHEN isa.sales_price <= 19
AND isa.report_source = 'storeX' THEN
1 * 1.25 * isa.quantity
WHEN isa.sales_price > 69
AND isa.report_source = 'storeY' THEN
6 * 1.25 * isa.quantity
WHEN isa.sales_price <= 69
AND isa.report_source = 'storeY' THEN
3 * 1.25 * isa.quantity
WHEN isa.sales_price <= 19
AND isa.report_source = 'storeY' THEN
1 * 1.25 * isa.quantity
WHEN xo.sales_price > 69
AND bb.country = 'NOR' THEN 6 * 1.25 * xo.quantity
WHEN xo.sales_price <= 69
AND bb.country = 'NOR' THEN 3 * 1.25 * xo.quantity
WHEN xo.sales_price > 69
AND bb.country <> 'NOR' THEN 6 * xo.quantity
WHEN xo.sales_price <= 69
AND bb.country <> 'NOR' THEN 3 * xo.quantity
END) AS 'Fee inc VAT(tot)'
FROM book_sales AS isa
INNER JOIN store AS BV
ON bv.store_id = isa.store_id
INNER JOIN financial_report AS xo
ON xo.identifiers = isa.identifiers
LEFT OUTER JOIN publisher AS BB
ON bb.publisher_id = bk.publisher_id
WHERE isa.sales_date >= CONVERT(DATETIME, #startDate, 20)
AND isa.sales_date < Dateadd(day, 1, ( CONVERT(DATETIME, #endDate, 20
) ))
GROUP BY bb.name,
bb.country
There are a few problems to sort out :
1- The total might be affected by NULL values, I suggest:
Sum(CASE
WHEN isa.report_source = 'storeX'
or isa.report_source = 'storeY' THEN
isnull(isa.quantity,0) * isnull(xo.quantity,0)
ELSE 0 END) AS 'Total quantity',
2- The case evaluation should be in order. For example:
WHEN isa.sales_price <= 69
AND isa.report_source = 'storeX' THEN
3 * 1.25 * isa.quantity
WHEN isa.sales_price <= 19
AND isa.report_source = 'storeX' THEN
1 * 1.25 * isa.quantity
<= 19 will never happen because it is also <= 69 and therefore the <=69 will evaluate true.
3- Cardinality between tables might be 1 to many so the values are summed multiple times when they shouldn't. You may need to select distinct or aggregate or flatten out some of the tables in the join to avoid this issue.

Comma Separated Value to Multiple BIT Columns

Hy , I have multiple values and i need a list of checks
ex:
1,2,4,
3,4, should be :
day1 day2 day3 day4
_1____1____0____1
_0____0____1____1
one method is
CAST(CASE WHEN PATINDEX('1,', [day]) > 0 THEN 1 ELSE 0 END AS BIT) as [day1],
CAST(CASE WHEN PATINDEX('2,', [day]) > 0 THEN 1 ELSE 0 END AS BIT) as [day2],
CAST(CASE WHEN PATINDEX('3,', [day]) > 0 THEN 1 ELSE 0 END AS BIT) as [day3],
CAST(CASE WHEN PATINDEX('4,', [day]) > 0 THEN 1 ELSE 0 END AS BIT) as [day4]
please help me with a better method because i have multiple columns
thanks
You can use a string split function of your choice with pivot.
declare #T table
(
ID int identity,
day varchar(20)
)
insert into #T values
('1,2,4,'),
('3,4,')
select isnull(P.[1], 0) as day1,
isnull(P.[2], 0) as day2,
isnull(P.[3], 0) as day3,
isnull(P.[4], 0) as day4
from
(
select T.ID, S.s, 1 as x
from #T as T
cross apply dbo.Split(',', T.day) as S
) as T
pivot (min(T.x) for T.s in ([1],[2],[3],[4])) as p
Result:
day1 day2 day3 day4
1 1 0 1
0 0 1 1
You could use the split function outlined here and then pivot the values into columns.
OR!
This answer looks like the same thing you're trying to do.
Use a second table to store valid days and then query on it. See this fiddle.
EDIT
See updated fiddle, or code below:
create table test (day1 varchar(8), day2 varchar(8), day3 varchar(8), day4 varchar(8));
insert into test (day1, day2, day3, day4) values ('day1', 'day2', 'day3', 'day4');
create table valid_days (valid_day_no int);
insert into valid_days values (1), (2), (4);
select cast (case when exists(select 1 from valid_days where valid_day_no = substring(day1, 4, len(day1))) then 1 else 0 end as bit) day1,
cast (case when exists(select 1 from valid_days where valid_day_no = substring(day2, 4, len(day2))) then 1 else 0 end as bit) day2,
cast (case when exists(select 1 from valid_days where valid_day_no = substring(day3, 4, len(day3))) then 1 else 0 end as bit) day3,
cast (case when exists(select 1 from valid_days where valid_day_no = substring(day1, 4, len(day4))) then 1 else 0 end as bit) day4
from test;
Note that SQL is a fixed column language, you need to use a programming language to dynamically build variable length column queries.