Shorten SQL update query - sql

Is there a way to shorten this update query? I'm new to this and not sure how can I further shorten it
UPDATE [Tbl_SS_Utilization(F03)_Copy1]
SET [WW0] = 0
WHERE [WW0] IS NULL
UPDATE [Tbl_SS_Utilization(F03)_Copy1]
SET [WW0+1] = 0
WHERE [WW0+1] IS NULL
UPDATE [Tbl_SS_Utilization(F03)_Copy1]
SET [WW0+2] = 0
WHERE [WW0+2] IS NULL
UPDATE [Tbl_SS_Utilization(F03)_Copy1]
SET [WW0+3] = 0
WHERE [WW0+3] IS NULL
UPDATE [Tbl_SS_Utilization(F03)_Copy1]
SET [WW0+4] = 0
WHERE [WW0+4] IS NULL
UPDATE [Tbl_SS_Utilization(F03)_Copy1]
SET [WW0+5] = 0
WHERE [WW0+5] IS NULL

I don't know what RDMBS you're using, but your posted SQL looks like T-SQL (for Microsoft SQL Server or Sybase), in that case then this single UPDATE statement should do the trick:
UPDATE
[Tbl_SS_Utilization(F03)_Copy1]
SET
[WW0] = CASE WHEN [WW0] IS NULL THEN 0 ELSE [WW0] END,
[WW0+1] = CASE WHEN [WW0+1] IS NULL THEN 0 ELSE [WW0+1] END,
[WW0+2] = CASE WHEN [WW0+2] IS NULL THEN 0 ELSE [WW0+2] END,
[WW0+3] = CASE WHEN [WW0+3] IS NULL THEN 0 ELSE [WW0+3] END,
[WW0+4] = CASE WHEN [WW0+4] IS NULL THEN 0 ELSE [WW0+4] END,
[WW0+5] = CASE WHEN [WW0+5] IS NULL THEN 0 ELSE [WW0+5] END
WHERE
[WW0] IS NULL OR
[WW0+1] IS NULL OR
[WW0+2] IS NULL OR
[WW0+3] IS NULL OR
[WW0+4] IS NULL OR
[WW0+5] IS NULL
Or with COALESCE (or ISNULL if you're feeling brave):
UPDATE
[Tbl_SS_Utilization(F03)_Copy1]
SET
[WW0] = COALESCE( [WW0] , 0 ),
[WW0+1] = COALESCE( [WW0+1], 0 ),
[WW0+2] = COALESCE( [WW0+2], 0 ),
[WW0+3] = COALESCE( [WW0+3], 0 ),
[WW0+4] = COALESCE( [WW0+4], 0 ),
[WW0+5] = COALESCE( [WW0+5], 0 )
WHERE
[WW0] IS NULL OR
[WW0+1] IS NULL OR
[WW0+2] IS NULL OR
[WW0+3] IS NULL OR
[WW0+4] IS NULL OR
[WW0+5] IS NULL

One update for all.
UPDATE [Tbl_SS_Utilization(F03)_Copy1]
SET
[WW0] = COALESCE([WW0], 0)
, [WW0+1] = COALESCE([WW0+1], 0)
, [WW0+2] = COALESCE([WW0+2], 0)
, [WW0+3] = COALESCE([WW0+3], 0)
, [WW0+4] = COALESCE([WW0+4], 0)
, [WW0+5] = COALESCE([WW0+5], 0)
WHERE ([WW0] & [WW0+1] & [WW0+2] & [WW0+3] & [WW0+4] & [WW0+5]) IS NULL;
test

Related

IF Else statements in SQL Update Query

I want to write if else in SQL Server Update Query.
UPDATE [dbo].[TempTable]
SET [Level1] = CASE WHEN A = -1 THEN 0 ELSE A END
,[Level2] = CASE WHEN A = -1 THEN 0 ELSE A END;
You need to use CASE in such scenarios. Try the above query..
If you insist on using IF, you can try the following:
IF
IF A = -1 BEGIN
UPDATE [dbo].[TempTable]
SET [Level1] = 0
,[Level2] = 0
END
ELSE BEGIN
UPDATE [dbo].[TempTable]
SET [Level1] = A
,[Level2] = A
END
IIF
UPDATE [dbo].[TempTable]
SET [Level1] = IIF(A = -1, 0, A)
,[Level2] = IIF(A = -1, 0, A)
You can use CASE statement, and If "A" is one of the column in your dbo.TempTable
DECLARE #Table TABLE(A INT,Level1 INT,Level2 INT)
INSERT #Table
SELECT -1, NULL, NULL UNION ALL
SELECT 1,NULL,NULL
UPDATE t SET
Level1 = CASE WHEN A = -1 THEN 0 ELSE A END,
Level2 = CASE WHEN A = -1 THEN 0 ELSE A END
FROM #Table t
SELECT * FROM #Table
-- Result
A Level1 Level2
-1 0 0
1 1 1
With case or IIF ;)
UPDATE [dbo].[TempTable]
SET [Level1] = IIF(A = -1 , 0 , A), [Level2] = IIF(A = -1 , 0 , A)
This will work:
UPDATE [dbo].[TempTable]
SET [Level1] = IIF(A = -1, 0, A), [Level2] = IIF(A = -1, 0, A);

SQL working strange

When I execute this SQL code:
select id, opis, vidrabota, tipprov, hitnost, valuta, drzava, zbirnaprov, tip_zbirprov, kanal
from dev_1450autoebanktip
where opis is null or Opis like case when isnull('','') = '' then Opis else '%' + '' + '%' end
and VidRabota = case when isnull('','') = '' then VidRabota else '' end
and TipProv = case when isnull(0,0) = 0 then TipProv else 0 end
and Valuta = case when isnull('','') = '' then Valuta else '' end
and drzava is null or Drzava = case when isnull('','') = '' then Drzava else '' end
I get this set of results:
But when I add one more condition (last row):
select id, opis, vidrabota, tipprov, hitnost, valuta, drzava, zbirnaprov, tip_zbirprov, kanal
from dev_1450autoebanktip
where opis is null or Opis like case when isnull('','') = '' then Opis else '%' + '' + '%' end
and VidRabota = case when isnull('','') = '' then VidRabota else '' end
and TipProv = case when isnull(0,0) = 0 then TipProv else 0 end
and Valuta = case when isnull('','') = '' then Valuta else '' end
and drzava is null or Drzava = case when isnull('','') = '' then Drzava else '' end
and KANAL = case when isnull(0,0) = 0 then KANAL else 0 end
I am losing one row in the result. What is causing this change?
Kanal is NULL in the last row.
and KANAL = case when isnull(0,0) = 0 then KANAL else 0 end
boils down to
and KANAL = KANAL
But this is not true for NULL, because NULL is the unknown value. When comparing null with null the result is neither true nor false, but unknown. Thus the added criteria dismisses the last record.
There is one thing I'd like to add: Use parentheses when mixing AND and OR. For instance
a = b or a = c and d = e
means
a = b or (a = c and d = e)
because AND has precedence over OR and you may want the expression to mean
(a = b or a = c) and d = e
Use parentheses in order to avoid any mistakes.

SSMS 2008 Conversion failed when converting the varchar value '2.126' to data type int

I'm new to SQL and I'm using SQL Server 2008 Management Studio. The below code isn't working due to a decimal being converted to an INT. From similar issues I can see that I need to use CONVERT, but unsure how to use this in my code?
DROP TABLE [DBO].[STEP9_OUTPUT]
GO
SELECT
S8.*,
CAST(CASE
WHEN S8.ERROR_TRANSACTION = 'N'
THEN NOERROR_VALUE
WHEN S8.SOURCE_SYSTEM_IND = 'P'
THEN P_VALUE
ELSE A_VALUE
END AS FLOAT) AS CORRECTED_PRICE
INTO STEP9_OUTPUT
FROM
(SELECT
S8.*,
CASE
WHEN S8.SOURCE_SYSTEM_IND = 'P' AND DIVRATE = 'Y'
THEN P_VALUE_DIV
WHEN S8.SOURCE_SYSTEM_IND = 'P' AND DIVRATE = 'N'
THEN P_VALUE_MULT
ELSE NULL
END AS P_VALUE
FROM
(SELECT
S8.*,
CASE
WHEN S8.SOURCE_SYSTEM_IND = 'P' AND
S8.ERROR_TRANSACTION = 'Y' AND
DIVRATE = 'N' AND S8.FN > 0
THEN S8.FN
WHEN S8.UNITS_INFUND_FOR_TRADE > 0
THEN S8.FTP
WHEN S8.FJFG = 'N' AND S8.RATE IS NULL
THEN S8.FB / 100 * 1
WHEN S8.FJFG = 'N' AND S8.RATE IS NOT NULL
THEN S8.FB / 100 * S8.RATE
WHEN S8.FJFG <> 'N' AND S8.RATE IS NULL
THEN 1 * 1
WHEN S8.FJFG <> 'N' AND S8.RATE IS NOT NULL
THEN 1 * S8.RATE
ELSE NULL
END AS P_VALUE_MULT,
CASE
WHEN S8.SOURCE_SYSTEM_IND = 'P' AND
S8.ERROR_TRANSACTION = 'Y' AND
[DIVRATE] = 'Y' AND S8.FN > 0
THEN S8.FN
WHEN S8.UNITS_INFUND_FOR_TRADE > 0
THEN S8.FTP
WHEN S8.FJFG = 'N' AND S8.RATE IS NULL
THEN S8.FB / 100
WHEN S8.FJFG = 'N' AND S8.RATE IS NOT NULL
THEN S8.FB / (100 / S8.RATE)
ELSE NULL
END AS P_VALUE_DIV
FROM
(SELECT
S8.*,
CASE
WHEN S8.ERROR_TRANSACTION = 'N'
THEN FUND_UNIT_PRICE_FOR_TRADE
ELSE NULL
END AS NOERROR_VALUE,
CASE
WHEN S8.SOURCE_SYSTEM_IND = 'A' AND
S8.ERROR_TRANSACTION = 'Y' AND
S8.ASSET_CODE = 'XX'
THEN S8.FUND_BID_VALUE
ELSE NULL
END AS A_VALUE,
CASE
WHEN S8.FACURR = 'SEK' OR S8.FACURR = 'JPY'
THEN 'Y'
ELSE 'N'
END AS DIVRATE
FROM
STEP8_OUTPUT S8) S8
) S8
) S8
SELECT CAST(CAST('2.126' as decimal) as int)

How to count non-null/non-blank values in SQL

I have data like the following:
And what I want is to count the PONo, PartNo, and TrinityID fields with a value in them, and output data like this:
How can I do this counting in SQL?
select
Job_number, Item_code,
case when RTRIM(PONo) = '' or PONo is null then 0 else 1 end +
case when RTRIM(PartNo) = '' or PartNo is null then 0 else 1 end +
case when RTRIM(TrinityID) = '' or TrinityID is null then 0 else 1 end
as [Count]
from YourTable
Try this:
select Job_Number = t.Job_Number ,
Item_Code = t.Item_Code ,
"Count" = sum( case ltrim(rtrim(coalesce( PONo , '' ))) when '' then 0 else 1 end
+ case ltrim(rtrim(coalesce( PartNo , '' ))) when '' then 0 else 1 end
+ case ltrim(rtrim(coalesce( TrinityID , '' ))) when '' then 0 else 1 end
)
from dbo.my_table t
group by t.Job_Number , t.Item_Code
If you want to exclude data where all the tested fields are null or empty, add a having clause:
having sum( case ltrim(rtrim(coalesce( PONo , '' ))) when '' then 0 else 1 end
+ case ltrim(rtrim(coalesce( PartNo , '' ))) when '' then 0 else 1 end
+ case ltrim(rtrim(coalesce( TrinityID , '' ))) when '' then 0 else 1 end
) > 0
Easy!

SQL geting Top X number of rows

i want to get only the top x number of the query. where the x will be send by parameter how can i do this?
I know i can take it as string and exec it later but i find it very cumbersome.
This the query i have and #ArticleNo is the parameter i want to take as x.
Create proc [dbo].[GW2_Report_SlowFastMovingArticle]
#ArtKey bigint = null,
#ArtCatKey int= null,
#ArtGroupKey int= null,
#ArtTypeKey int= null,
#MaterialKey int= null,
#ColorKey int= null,
#VendorTypeKey int = null,
#VendorKey bigint = null,
#FromDate datetime = null,
#ToDate datetime = null,
#MovingType int = 0,
#PerformanceType int = 0,
#ArticleNo int = 10,
#OutletKey int = null
AS
BEGIN
SELECT
dbo.Sal_POSDet.ArtKey,
dbo.ArtWithVendor.ArtCode,
dbo.ArtWithVendor.ArtName,
Sum(isnull(dbo.Sal_POSDet.Qty,0))as Pair,
Sum(isnull(dbo.Sal_POSDet.Total,0)) as TurnOver
into #temp FROM
dbo.Sal_POS INNER JOIN
dbo.Sal_POSDet ON
dbo.Sal_POS.SalesKey = dbo.Sal_POSDet.SalesKey INNER JOIN
dbo.ArtWithVendor ON
dbo.Sal_POSDet.ArtKey = dbo.ArtWithVendor.ArtKey
WHERE
Sal_POS.IsHold=0 and
Sal_POS.SalesDate between #FromDate and #ToDate and
CASE WHEN #ArtKey is null THEN 1 WHEN ArtWithVendor.ArtKey =#ArtKey THEN 1 ELSE 0 END = 1
and CASE WHEN #ArtCatKey is null THEN 1 WHEN ArtWithVendor.ArtCatKey =#ArtCatKey THEN 1 ELSE 0 END = 1
and CASE WHEN #ArtGroupKey is null THEN 1 WHEN ArtWithVendor.ArtGroupKey = #ArtGroupKey THEN 1 ELSE 0 END = 1
and CASE WHEN #ArtTypeKey is null THEN 1 WHEN ArtWithVendor.ArtTypeKey = #ArtTypeKey THEN 1 ELSE 0 END = 1
and CASE WHEN #MaterialKey is null THEN 1 WHEN ArtWithVendor.MaterialKey = #MaterialKey THEN 1 ELSE 0 END = 1
and CASE WHEN #ColorKey is null THEN 1 WHEN ArtWithVendor.ColorKey = #ColorKey THEN 1 ELSE 0 END = 1
and CASE WHEN #VendorKey is null THEN 1 WHEN ArtWithVendor.VendorKey = #VendorKey THEN 1 ELSE 0 END = 1
and CASE WHEN #VendorTypeKey is null THEN 1 WHEN ArtWithVendor.VendorTypeKey = #VendorTypeKey THEN 1 ELSE 0 END = 1
and CASE WHEN #OutLetKey is null THEN 1 WHEN Sal_POS.OutLetKey = #OutLetKey THEN 1 ELSE 0 END = 1
Group by
dbo.Sal_POSDet.ArtKey,
dbo.ArtWithVendor.ArtCode,
dbo.ArtWithVendor.ArtName
if(#PerformanceType=0 and #MovingType=0)
begin
select * from #temp
order by Pair asc
end
if(#PerformanceType=0 and #MovingType=1)
begin
select * from #temp
order by Pair desc
end
if(#PerformanceType=1 and #MovingType=0)
begin
select * from #temp
order by turnover asc
end
if(#PerformanceType=1 and #MovingType=1)
begin
select * from #temp
order by turnover desc
end
END
Try this...
select TOP(#ArticleNo) *
from #temp
Use:
SELECT TOP(#ArticleNo)
Therefore:
SELECT TOP(#ArticleNo)
dbo.Sal_POSDet.ArtKey,
dbo.ArtWithVendor.ArtCode,
dbo.ArtWithVendor.ArtName,
Sum(isnull(dbo.Sal_POSDet.Qty,0))as Pair,
Sum(isnull(dbo.Sal_POSDet.Total,0)) as TurnOver
into #temp FROM
dbo.Sal_POS INNER JOIN
dbo.Sal_POSDet ON
dbo.Sal_POS.SalesKey = dbo.Sal_POSDet.SalesKey INNER JOIN
dbo.ArtWithVendor ON
dbo.Sal_POSDet.ArtKey = dbo.ArtWithVendor.ArtKey
WHERE
Sal_POS.IsHold=0 and
Sal_POS.SalesDate between #FromDate and #ToDate and
CASE WHEN #ArtKey is null THEN 1 WHEN ArtWithVendor.ArtKey =#ArtKey THEN 1 ELSE 0 END = 1
and CASE WHEN #ArtCatKey is null THEN 1 WHEN ArtWithVendor.ArtCatKey =#ArtCatKey THEN 1 ELSE 0 END = 1
and CASE WHEN #ArtGroupKey is null THEN 1 WHEN ArtWithVendor.ArtGroupKey = #ArtGroupKey THEN 1 ELSE 0 END = 1
and CASE WHEN #ArtTypeKey is null THEN 1 WHEN ArtWithVendor.ArtTypeKey = #ArtTypeKey THEN 1 ELSE 0 END = 1
and CASE WHEN #MaterialKey is null THEN 1 WHEN ArtWithVendor.MaterialKey = #MaterialKey THEN 1 ELSE 0 END = 1
and CASE WHEN #ColorKey is null THEN 1 WHEN ArtWithVendor.ColorKey = #ColorKey THEN 1 ELSE 0 END = 1
and CASE WHEN #VendorKey is null THEN 1 WHEN ArtWithVendor.VendorKey = #VendorKey THEN 1 ELSE 0 END = 1
and CASE WHEN #VendorTypeKey is null THEN 1 WHEN ArtWithVendor.VendorTypeKey = #VendorTypeKey THEN 1 ELSE 0 END = 1
and CASE WHEN #OutLetKey is null THEN 1 WHEN Sal_POS.OutLetKey = #OutLetKey THEN 1 ELSE 0 END = 1
Group by
dbo.Sal_POSDet.ArtKey,
dbo.ArtWithVendor.ArtCode,
dbo.ArtWithVendor.ArtName
Alternatively, add the following before your SELECT query:
IF #ArticleNo IS NOT NULL
BEGIN
SET ROWCOUNT #ArticleNo
END
Then after your SELECT query you need to reset the ROWCOUNT by doing:
IF #ArticleNo IS NOT NULL
BEGIN
SET ROWCOUNT 0
END
Therefore, overall it will be something like:
IF #ArticleNo IS NOT NULL
BEGIN
SET ROWCOUNT #ArticleNo
END
SELECT
dbo.Sal_POSDet.ArtKey,
dbo.ArtWithVendor.ArtCode,
dbo.ArtWithVendor.ArtName,
Sum(isnull(dbo.Sal_POSDet.Qty,0))as Pair,
Sum(isnull(dbo.Sal_POSDet.Total,0)) as TurnOver
into #temp FROM
dbo.Sal_POS INNER JOIN
dbo.Sal_POSDet ON
dbo.Sal_POS.SalesKey = dbo.Sal_POSDet.SalesKey INNER JOIN
dbo.ArtWithVendor ON
dbo.Sal_POSDet.ArtKey = dbo.ArtWithVendor.ArtKey
WHERE
Sal_POS.IsHold=0 and
Sal_POS.SalesDate between #FromDate and #ToDate and
CASE WHEN #ArtKey is null THEN 1 WHEN ArtWithVendor.ArtKey =#ArtKey THEN 1 ELSE 0 END = 1
and CASE WHEN #ArtCatKey is null THEN 1 WHEN ArtWithVendor.ArtCatKey =#ArtCatKey THEN 1 ELSE 0 END = 1
and CASE WHEN #ArtGroupKey is null THEN 1 WHEN ArtWithVendor.ArtGroupKey = #ArtGroupKey THEN 1 ELSE 0 END = 1
and CASE WHEN #ArtTypeKey is null THEN 1 WHEN ArtWithVendor.ArtTypeKey = #ArtTypeKey THEN 1 ELSE 0 END = 1
and CASE WHEN #MaterialKey is null THEN 1 WHEN ArtWithVendor.MaterialKey = #MaterialKey THEN 1 ELSE 0 END = 1
and CASE WHEN #ColorKey is null THEN 1 WHEN ArtWithVendor.ColorKey = #ColorKey THEN 1 ELSE 0 END = 1
and CASE WHEN #VendorKey is null THEN 1 WHEN ArtWithVendor.VendorKey = #VendorKey THEN 1 ELSE 0 END = 1
and CASE WHEN #VendorTypeKey is null THEN 1 WHEN ArtWithVendor.VendorTypeKey = #VendorTypeKey THEN 1 ELSE 0 END = 1
and CASE WHEN #OutLetKey is null THEN 1 WHEN Sal_POS.OutLetKey = #OutLetKey THEN 1 ELSE 0 END = 1
Group by
dbo.Sal_POSDet.ArtKey,
dbo.ArtWithVendor.ArtCode,
dbo.ArtWithVendor.ArtName
IF #ArticleNo IS NOT NULL
BEGIN
SET ROWCOUNT 0
END
However using ROWCOUNT is not ideal as it will mess with your sub-query results.