Need to add 1 pos. to the substring in this SQL - sql

This sql is working but the second substring, is the order num. For these we need to add a '0' at the end, to make it 8 pos now. Not sure how to do this in SQL.
SELECT
ALL SUBSTR(UANOTL,1,4) AS CODE1, SUBSTR(UANOTL,5,7) AS ORDER#,
UAATHN, UANOTD
FROM ASTDTA.NOTEH1 T01
WHERE SUBSTR(UANOTL,1,4) = 'REM '

You need the concatenation operator:
SELECT ALL
SUBSTR(UANOTL,1,4) AS CODE1,
SUBSTR(UANOTL,5,7) || '0' AS ORDER#,
UAATHN, UANOTD
FROM ASTDTA.NOTEH1 T01
WHERE SUBSTR(UANOTL,1,4) = 'REM '

you just put an & operator before the string and the 0 you want to add
so 0 in front would be
select ('0' & ORDER#)
and at the end would be
select (ORDER# & '0')

Related

Oracle Regex at least "1" match in a serie

I have a question related with oracle sql regex function.
I have a series of zeros and ones. It can vary as:
Ex:
1111000
000001
0101111
10000
If there is at least one "1" in this serie, then I want to output as "1"
otherwise I want to ouput "0". So I tried something like:
SELECT REGEXP_REPLACE('1,1,1,0','[0,]||[1]+','') FROM DUAL
However this just outputs "1's" out of series excluding "0"
So my question: How can I achieve this on oracle sql?
If I understand well and you only need to check whether a string contains '1' or not, you may not need regexp and INSTR could be enough:
select case
when instr(yourString, '1') = 0
then '1 is not in the string'
else '1 is in the string'
end
from dual
`LIKE %1%' will work for you as well...
with dt as (
select '00000000' seq from dual union all
select '00011000' seq from dual)
select
seq,
case when seq like '%1%' then 1 else 0 end as res
from dt;
SEQ RES
-------- ----------
00000000 0
00011000 1
Later on I also figured out that this also worked for me:
SELECT
REGEXP_REPLACE( 'MY_STRING' , '.?+1?[0,]', '') as COLUMN_NAME
FROM dual;

How do I use an IN statement in SSRS Formula

Is there an easy way to do an IN statement or something similar in a SSRS formula for an iff statement comparison without having to repeat a switch 16 times?
This is what I am looking to accomplish without having to write a statement or a separate OR ie(Fields!FieldName.Value = "01" OR Fields!FieldName.Value = "02"...etc) for each value:
=iif((Fields!FieldName.Value IN
("01","02","03","06","08","09","10","12","15","19"),"TypeA",
iff((Fields!ProdCode.Value IN ("04","07","11","13","14","16"),
"TypeB","TypeC")
Or this:
=switch(
Instr( "," & "01,02,03,06,08,09,10,12,15,19" & ",", "," & Fields!FieldName.Value & ",") > 0 ,"TypeA",
Instr( "," & "04,07,11,13,14,16" & ",", "," & Fields!ProdCode.Value & ",") > 0 ,"TypeB",
True, "TypeC")
I have mocked up an example of joining to a table that is generated in the sql. This is more efficient than doing it in the report
SELECT a,b,c,d, etc
, Lookup.FieldName, Lookup.TypeLabel
FROM Tables INNER JOIN
(SELECT '01' AS FieldName, "TypeA" as TypeLabel
UNION ALL
SELECT '02' , "TypeA"
UNION ALL
SELECT '03' , "TypeA"
UNION ALL
SELECT '04' , "TypeB"
UNION ALL
...
SELECT '18' , "TypeC"
UNION ALL
SELECT '19' , "TypeC") LookUp
ON Tables.FieldName = Lookup.FieldName
Try this:
=Switch(
Array.IndexOf(Split("01,02,03,06,08,09,10,12,15,19",","), Fields!FieldName.Value)>-1,"TypeA",
Array.IndexOf(Split("04,07,11,13,14,16",","),Fields!FieldName.Value)>-1,"TypeB",
true,"TypeC"
)
Let me know if this helps.

Get max number from table add one and check with specific convention

I have to produce artikel number based on some convention, and this convention is as below
The number of digits
{1 or 2 or 3}.{4 or 5}.{n}
example products numbers:
7.1001.1
1.1453.1
3.5436.1
12.7839.1
12.3232.1
13.7676.1
3.34565.1
12.56433.1
247.23413.1
The first part is based on producent, and every producent has its own number. Let's say Rebook - 12, Nike - 256 and Umbro - 3.
I have to pass this number and check in table if there are some rows containing it e.g i pass 12 then i should get everything which starts from 12.
and now there should be three cases what to do:
1st CASE: no rows at the table:
then retrieve 1001
2nd case: if there are rows
so for sure there is already at least one:
12.1001.1
and more if they are let's say:
12.1002.1
12.1003.1
...
12.4345.1
so should be retreived next one so: 4346
and if there are already 5-digits for this product so let's say:
12.1002.1
12.1003.1
...
12.9999.1
so should be retreived next one so: 10001
3rd case: in fact same as 2nd but if it rached 9999 for second part:
12.1001.1
...
12.9999.1
then returned should be: 10001
or
12.1002.1
12.1003.1
...
12.9999.1
12.10001.1
12.10002.1
so should be retreived next one so: 10003
Hope you know what i mean
I already have started something. This code is taking producent number - looking for all rows starting with it and then just simply adding 1 to the second part unfortunetly i am not sure how should i change it according to those 3 cases.
select
parsename(max(nummer), 3) + '.' -- 3
+ ltrim(max(cast(parsename(nummer, 2) as int) +1)) -- 5436 -> 5437
+ '.1'
from tbArtikel
where Nummer LIKE '3.%'
Counting on your help. If something unclear let me know.
Additional question:
Using cmd As New SqlCommand("SELECT CASE WHEN r.number Is NULL THEN 1001
WHEN r.number = 9999 THEN 10001
Else r.number + 1 End number
FROM (VALUES(#producentNumber)) AS a(art) -- this will search this number within inner query And make case..
LEFT JOIN(
-- Get producent (in Like) number And max number Of it (without Like it Get all producent numbers And their max number out Of all
SELECT PARSENAME(Nummer, 3) art,
MAX(CAST(PARSENAME(Nummer, 2) AS INT)) number
FROM tbArtikel WHERE Nummer Like '#producentNumber' + '[.]%'
GROUP BY PARSENAME(Nummer, 3)
) r
On r.art = a.art", con)
cmd.CommandType = CommandType.Text
cmd.Parameters.AddWithValue("#producentNumber", producentNumber)
A fairly straight forward way is to (ab)use PARSENAME to split the string to be able to extract the current maximum. An outer query can then just implement the rules for the value being missing/9999/other.
The value (12 here) is inserted in a table value constructor to be able to detect a missing value using a LEFT JOIN.
SELECT CASE WHEN r.number IS NULL THEN 1001
WHEN r.number = 9999 THEN 10001
ELSE r.number + 1 END number
FROM ( VALUES(12) ) AS a(category)
LEFT JOIN (
SELECT PARSENAME(prodno, 3) category,
MAX(CAST(PARSENAME(prodno, 2) AS INT)) number
FROM products
GROUP BY PARSENAME(prodno, 3)
) r
ON r.category = a.category;
An SQLfiddle to test with.
As a further optimization, you could add a WHERE prodno LIKE '12[.]%' in the inner query to not parse through un-necessary rows.
I don't fully understand what you're asking for. I am unsure about the examples...but if i was doing it I'd try to break the field into 3 fields first and then do something with them.
sqlfiddle
SELECT nummer,LEFT(nummer,first-1) as field1,
RIGHT(LEFT(nummer,second-1),second-first-1) as field2,
RIGHT(nummer,LEN(nummer)-second) as field3
FROM
(SELECT nummer,
CHARINDEX('.',nummer) as first,
CHARINDEX('.',nummer,CHARINDEX('.',nummer)+1)as second
from tbArtikel)T
Hopefully with the 3 fields broken up, it's much easier to apply logics to them now.
update:
Okay i reread your question and i sort of know what you're trying to get at..
if user search for a value that doesn't exist for example 8.
Then you want 1001 returned
if they search for anything else that has results then return the max+1
unless it's 9999 then return 10001.
If this is correct then check this sqlfiddle2
DECLARE #search varchar(20)
SET #search = '8'
SELECT field1,max(nextvalue) as nextvalue FROM
(SELECT field1,
MAX(CASE (field2)
WHEN 9999 THEN 10001
ELSE field2+1
END) as nextvalue
FROM
(SELECT nummer,
CAST(LEFT(nummer,first-1) as INTEGER) as field1,
CAST(RIGHT(LEFT(nummer,second-1),second-first-1) as INTEGER) as field2,
CAST(RIGHT(nummer,LEN(nummer)-second) as INTEGER) as field3
FROM
(SELECT nummer,
CHARINDEX('.',nummer) as first,
CHARINDEX('.',nummer,CHARINDEX('.',nummer)+1)as second
FROM tbArtikel
)T
)T2
GROUP BY field1
UNION
SELECT CAST (#search as INTEGER)as field1 ,1001
)T3
WHERE field1 = #search
GROUP BY field1
Just change the #search variable to see it's results
I think there might be a cleaner way to do this but it's not coming to me right now :(
If you really can't add 2 new fields (is't probably the simplest and fastest solution), and probably can't add functional index, you must extract 2nd part number and get max of this, increment, then concatenate with your condition 1st part number and '.1' at the end:
SELECT :par1 || '.' || (Max(To_Number(SubStr(nummer, dot1 + 1, dot2 - dot1 -1 ))) + 1) || '.1' NEW_number
--SELECT SubStr(nummer, 1, dot1 - 1) N1st, SubStr(nummer, dot1 + 1, dot2 - dot1 -1 ) N2nd, SubStr(nummer, dot2 + 1) N1th
FROM (
SELECT nummer, InStr(nummer, '.') dot1, InStr(nummer, '.', 1, 2) dot2
FROM tbArtikel
WHERE nummer LIKE :par1 || '.%')
;
--GROUP BY SubStr(nummer, 1, dot1 – 1)
it was for oracle sql, i don't have sql-serwer to test, but probably this is simplest answer:
select #par1 + '.' + (select max(cast(SUBSTRING(nummer, CHARINDEX( '.', nummer, 1 ) +1, CHARINDEX( '.', nummer, CHARINDEX( '.', nummer, 1 ) +1 ) - CHARINDEX( '.', nummer, 1 ) -1) as int)) + 1 from tbArtikel where nummer LIKE #par1 || '.%') + '.1'
if parsename(nummer, 2) is you defined function to get 2nd number then:
select #parm + '.' + (max(cast(parsename(nummer, 2) as int)) + 1) + '.1'
from tbArtikel
where Nummer LIKE #parm + '.%'

Order by Function Results in Union Statement

I have a query that has multiple union statements where the last union statements results are derived from a function. I want to know how to sort the resultset based on the vchLastName of the function results. Here is the basis of the stored procedure.
select ID, objtype, Descr=coalesce(v.acctName, x.Descr), x.ihhid
from (
-----select statements----
UNION ALL
SELECT
pn.iPartyID,
'CONTACT',
ISNULL(vchFirstName,'') + ' ' + ISNULL(vchLastName,'') + ' ' +
CASE WHEN vchGoesBy IS NOT NULL THEN '(' + vchGoesBy + ')' ELSE ISNULL(vchGoesBy,'') END,
pn.iHHID
FROM CRM.dbo.cfn_PartyNameSearch(1, 'test') pn
WHERE pn.cPartyType = 'C'
)
x left join tableName v on v.id = x.id
and x.ObjType='ACCOUNT'
I want to sort by the pn.vchLastName for CONTACT. the other results sorting isn't a big deal honestly, and I am not able to edit the function that gives the results.
This general idea will work. You can work out the details
select 2 sortfield1
, whatever aliasName
from etc
union all
select 1 sortfield1
, yourFunctionResult aliasName
from etc
order by sortfield1, aliasName
Ordering takes place towards the end of the query execution, at least after all the data has been selected. Therefore you will have to order the entire result set at the end of the query. IIRC there is not conditonal ordering in T-SQL.

sql select in string with a split function?

how can i make a select from not normed table.
i have the table like this:
this table is not norme BNF 2.
i just want to select the NO_ID where DEPARTEMENT = something.
example:
when the input 44 then NO_ID =1
when the input 37 then NO_ID =3
when the input 13(not in table) then NO_ID = 5
of course when input = 44 it works:
SELECT [NO_ID]
FROM [T_TARIF_ZONE]
WHERE DEPARTEMENT = '44'
but how can i put in WHERE statement when the input = 37 or 13.
thanks you in advance,
Stev
try this:
SELECT [NO_ID]
FROM [T_TARIF_ZONE]
WHERE DEPARTEMENT like '%37%'
Please try:
select
NO_ID,
DEPARTMEMT
from
T
where
' '+DEPARTMEMT+' ' like
(case when #var=13 then ' FRANCE ' ELSE '% '+#var+' %' END)
Oracle version -
SELECT [NO_ID]
FROM [T_TARIF_ZONE]
WHERE INSTR(DEPARTEMENT, '44')>0 OR INSTR(DEPARTEMENT, '37')>0 OR INSTR(DEPARTEMENT, '13')>0
SQL Server version -
SELECT [NO_ID]
FROM [T_TARIF_ZONE]
WHERE PATINDEX('44', DEPARTEMENT)>0 OR PATINDEX('37', DEPARTEMENT)>0 OR PATINDEX('13', DEPARTEMENT)>0