db2 query returning 0 records - sql

I am trying to execute below query:
select * from trgdms.src_stm where trim(src_stm_code) in (select concat (concat('''', trim(replace(processed_src_sys_cd,',',''','''))),'''' ) from trgdms.batch_run_log where src_stm_cd_or_hub_cd='CTR' and file_process_dt='2015-06-19' and batch_id=42);
the src_stm_code column of table trgdms.src_stm have values like T19,T68,T73 etc. When I run the inner query alone i do get the correct result:
select concat (concat('''', trim(replace(processed_src_sys_cd,',',''','''))),'''' ) from trgdms.batch_run_log where src_stm_cd_or_hub_cd='CTR' and file_process_dt='2015-06-19' and batch_id=42
Result: 'T19','T68','T73'
Wondered if anyone has used something similar in db2?

Remove the concat part from the inner query. When you concatenate values, the list of values generated will be treated as a string and the query doesn't return any results.
select * from trgdms.src_stm where trim(src_stm_code)
in (select trim(replace(processed_src_sys_cd,',',''',''')) from trgdms.batch_run_log
where src_stm_cd_or_hub_cd='CTR' and file_process_dt='2015-06-19' and batch_id=42);

Related

A SQL Query to select certain strings in a folder path

I have a table with a column that contains the path to SSIS packages located in a drive. The entire folder path is populated in the column. I need a SQL query to get a section of the string within the folder path.
An example of record in the column_1.
/FILE "\"G:\Enterprise_Data\Packages\SSIS_Packages_Source_to_Target_Data_Snowflake.dtsx\""/CHECKPOINTING OFF /REPORTING E
All I am interested in extracting is the "SSIS_Packages_Source_to_Target_Data_Snowflake". Everything I have tried so far throws errors. The latest code I tried is:
SELECT SUBSTRING(Column_1, LEFT(CHARINDEX('dtsx', Column_1)), LEN(Column_1) - CHARINDEX('dtsx', Column_1)).
I would really appreciate some help with this.
Thanks!
Given you know the extension and its unlikely to appear elsewhere in the string, find it, and truncate to it. Do that in a CROSS APPLY so we can use the value multiple times.
Then find the nearest slash (using REVERSE) and use SUBSTRING from there to the end.
SELECT
SUBSTRING(Y.[VALUE], LEN(Y.[VALUE]) - PATINDEX('%\%', REVERSE(Y.[VALUE])) + 2, LEN(Y.[VALUE]))
FROM (
VALUES ('/FILE "\"G:\Enterprise_Data\Packages\SSIS_Packages_Source_to_Target_Data_Snowflake.dtsx\""/CHECKPOINTING OFF /REPORTING E')
) AS X ([Value])
CROSS APPLY (
VALUES (SUBSTRING(X.[Value], 1, PATINDEX('%.dtsx%', X.[Value])-1))
) AS Y ([Value]);
Returns:
SSIS_Packages_Source_to_Target_Data_Snowflake
Another possible way is this. not sure on the performance of it though
SELECT vt.[value]
FROM (
VALUES ('/FILE "\"G:\Enterprise_Data\Packages\SSIS_Packages_Source_to_Target_Data_Snowflake.dtsx\""/CHECKPOINTING OFF /REPORTING E')
) AS X ([Value])
OUTER APPLY (
SELECT * FROM STRING_SPLIT(x.Value,'\')
) vt
WHERE vt.[value] LIKE '%.dtsx'
Thank you #Dale K for your response and solutions provided. I was able to replicate the same for my query to obtain the result. Below is how I modified the query in my environment to fetch only the new string column1 after applying the string manipulations based on your solution:
SELECT SUBSTRING(Y.column1, LEN(Y.column1) - PATINDEX('%%', REVERSE(Y.column1)) +2, LEN(Y.column1))
FROM (SELECT column1 FROM CTE1) AS X ([column2])
CROSS APPLY (SELECT SUBSTRING(X.column2, 1, PATINDEX('%.dtsx%', X.column2)-1) FROM CTE1) AS Y ([column1])
I am actually query a CTE table (CTE1) to get my desired result. The issue is that, I have other columns in the CTE1 that I need to include in the final select query results, which of course should include the string manipulated results from Column1. Currently, I get errors when I try to include other columns in my final result from the CTE1 along with the resultset from the query above.
Example of final query:
Select Jobname,job_step,job_date,job_duration,Column1 (this will be the resultset from the string manipulation)FROM CTE1;
So, what I'm currently doing that is not working is as follows:
SELECT C1.Jobname,C1.job_step,C1.job_date,C1.job_duration,Column1 =(SELECT SUBSTRING(Y.column1, LEN(Y.column1) - PATINDEX('%\%', REVERSE(Y.column1)) +2, LEN(Y.column1)) FROM (SELECT column1 FROM CTE1) AS X ([column2]) CROSS APPLY (SELECT SUBSTRING(X.column2, 1, PATINDEX('%.dtsx%', X.column2)-1) FROM CTE1) AS Y ([column1])) FROM CTE1 C1
Please, how can I obtain the final results with all the above columns present in the resultsets?
Thank you.

Check if the first or second condition exists

I have a little problem selecting queries, namely when I want to check the first condition with the code below
select * from VL_Faktura_Queue where FAK_KundenNr=127849 AND (FAK_BoMatNr LIKE '%verk%' AND FAK_VerrechnetBis ='0001-01-01')
, it shows me one position, but when I add a condition where I want to check if there is a FAK_KundenNr with FAK_BomatNr LIKE '% Verk%' OR FAK_BoMatNr Like 'Zus%' also throws me different values that do not fall under FAK_KundenNr = 127849, as I can easily check that it returns my values for this KundenNr, where there is 1 OR 2 condition.
this is my query:
select * from VL_Faktura_Queue where FAK_KundenNr=127849
AND (FAK_BoMatNr LIKE '%verk%' AND FAK_VerrechnetBis ='0001-01-01') --this would be the first condition
or FAK_BoMatNr like 'Zus%' --and this the second condition
This is the individual selection I should get but in one query at the end
so my question is how can i get in one query select from these two query from the picture, thanks everyone for the help
Your parentheses are not sufficient. AND has precedence over OR, so you have FAK_KundenNr = 127849 AND (<first condition)> OR FAK_BoMatNr like 'Zus%'.
SELECT *
FROM VL_Faktura_Queue
WHERE FAK_KundenNr = 127849
AND
(
(FAK_BoMatNr LIKE '%verk%' AND FAK_VerrechnetBis = '0001-01-01')
or
FAK_BoMatNr LIKE 'Zus%'
);
In your requirement, you need to combine the "AND" operator with other logical "OR" operator.
SELECT *
FROM VL_Faktura_Queue
WHERE
(
( FAK_BoMatNr LIKE '%verk%'
AND FAK_VerrechnetBis = '0001-01-01'
) -- 1st Condition
or
(FAK_BoMatNr LIKE 'Zus%') -- 2nd Condition
)
AND FAK_KundenNr = 127849;
Please check if this solution is working for you.

How to use INTO and GROUP BY clause together

SELECT cast ( SUBSTRING ( CAST ("ProcessingDate" AS text), 5, 2 ) as integer),
COUNT(*) INTO resultValue1,resultValue2
FROM "DemoLogs"."Project"
WHERE "Addr" = 'Y' AND "ProcessingDate" >= 20160110
GROUP BY 1
ORDER BY 1;
In my database, the ProcessingDate is stored as YYYYMMDD. So, I am extracting its month from it.
This query is working fine if we remove the INTO clause but, I want to store the result to use it further.
So what should be the datatype of the variable resultValue1 and resultValue2 how to store the data(because data will be multiple).
As I am new to PostgreSQL I don't know how to do this can anybody help me out.
Here resultValue1 & resultValue2 will be tables not variables. you can group by using the column names.
Give some column alias names for both columns and group by using them.
You probably want this.
SELECT cast ( SUBSTRING ( cast ("ProcessingDate" as text),5 , 2 ) as
integer) AS resultValue1, COUNT(*) AS resultValue2
INTO <NewTable> --NewTable will be created with those two columns
FROM "DemoLogs"."Project"
-- conditions
Group By 1
-- other contitions/clauses
;
Kindly refer this INTO Documentation.
Hope this helps.
Try this:
SELECT cast ( SUBSTRING ( cast ("ProcessingDate" as text),5 , 2 ) as integer)resultValue1,
COUNT(*)resultValue2
INTO <Table Name>
FROM "DemoLogs"."Project"
WHERE "Addr" = 'Y'
AND "ProcessingDate" >= '20160110'
Group By 1
Order By 1;
Store the above query in the variable and remove that INTO clause from it.
So, query will be now :
query = SELECT cast ( SUBSTRING ( CAST ("ProcessingDate" AS text), 5, 2 ) as
integer),
COUNT(*)
FROM "DemoLogs"."Project"
WHERE "Addr" = 'Y' AND "ProcessingDate" >= 20160110
GROUP BY 1
ORDER BY 1;
Now declare result_data of type record and use in the following manner:
We are looping over result_data because it gives number of rows as output
and I have declared resultset of type text to store the result (as I needed further)
FOR result_data IN EXECUTE query
LOOP
RAISE NOTICE 'result : %',to_json(result_data);
resultset = resultset || to_json(result_data);
END LOOP;

How to aggragate integers in postgresql?

I have a query that gives list of IDs:
ID
2
3
4
5
6
25
ID is integer.
I want to get that result like that in ARRAY of integers type:
ID
2,3,4,5,6,25
I wrote this query:
select string_agg(ID::text,',')
from A
where .....
I have to convert it to text otherwise it won't work. string_agg expect to get (text,text)
this works fine the thing is that this result should later be used in many places that expect ARRAY of integers.
I tried :
select ('{' || string_agg(ID::text,',') || '}')::integer[]
from A
WHERE ...
which gives: {2,3,4,5,6,25} in type int4 integer[]
but this isn't the correct type... I need the same type as ARRAY.
for example SELECT ARRAY[4,5] gives array integer[]
in simple words I want the result of my query to work with (for example):
select *
from b
where b.ID = ANY (FIRST QUERY RESULT) // aka: = ANY (ARRAY[2,3,4,5,6,25])
this is failing as ANY expect array and it doesn't work with regular integer[], i get an error:
ERROR: operator does not exist: integer = integer[]
note: the result of the query is part of a function and will be saved in a variable for later work. Please don't take it to places where you bypass the problem and offer a solution which won't give the ARRAY of Integers.
EDIT: why does
select *
from b
where b.ID = ANY (array [4,5])
is working. but
select *
from b
where b.ID = ANY(select array_agg(ID) from A where ..... )
doesn't work
select *
from b
where b.ID = ANY(select array_agg(4))
doesn't work either
the error is still:
ERROR: operator does not exist: integer = integer[]
Expression select array_agg(4) returns set of rows (actually set of rows with 1 row). Hence the query
select *
from b
where b.id = any (select array_agg(4)) -- ERROR
tries to compare an integer (b.id) to a value of a row (which has 1 column of type integer[]). It raises an error.
To fix it you should use a subquery which returns integers (not arrays of integers):
select *
from b
where b.id = any (select unnest(array_agg(4)))
Alternatively, you can place the column name of the result of select array_agg(4) as an argument of any, e.g.:
select *
from b
cross join (select array_agg(4)) agg(arr)
where b.id = any (arr)
or
with agg as (
select array_agg(4) as arr)
select *
from b
cross join agg
where b.id = any (arr)
More formally, the first two queries use ANY of the form:
expression operator ANY (subquery)
and the other two use
expression operator ANY (array expression)
like it is described in the documentation: 9.22.4. ANY/SOME
and 9.23.3. ANY/SOME (array).
How about this query? Does this give you the expected result?
SELECT *
FROM b b_out
WHERE EXISTS (SELECT 1
FROM b b_in
WHERE b_out.id = b_in.id
AND b_in.id IN (SELECT <<first query that returns 2,3,4,...>>))
What I've tried to do is to break down the logic of ANY into two separate logical checks in order to achieve the same result.
Hence, ANY would be equivalent with a combination of EXISTS at least one of the values IN your list of values returned by the first SELECT.

Format sql column when using select

I have the following query to select record but i wan to format the column on the result set.
SELECT
COALESCE(dbo.tblMitchellLandscapeID.PatchSize,0) as PatchSize,
dbo.tblMitchellLandscape.MitchellLandscapeName
FROM tblMitchellLandscapeID
INNER JOIN dbo.tblMitchellLandscape
ON dbo.tblMitchellLandscapeID.MitchellLandscapeID=dbo.tblMitchellLandscape.MitchellLandscapeID
WHERE AssessmentVersionID = #AssessmentVersionID
"PatchSize" is a decimal value so it stored always like two decimals "15.10". All i trying to format to one decimal when the select statement is executed i wan to populate the result set like "15.1" rather than 15.10.
You can just cast it to the format you want:
SELECT CAST(COALESCE(li.PatchSize, 0) as decimal(5, 1)) as PatchSize,
l.MitchellLandscapeName
FROM tblMitchellLandscapeID li INNER JOIN
dbo.tblMitchellLandscape l
ON li.MitchellLandscapeID = l.MitchellLandscapeID
WHERE AssessmentVersionID = #AssessmentVersionID;
Notice the query is also easier to read (and write) if you use table aliases.