DB2 -Clause IN-Multiple Value - sql

The following code is working fine when the column 'generated_key ' return one value
WHERE code IN ( SELECT generated_key FROM List_agg )
CODE
generated_key
EU00100ST10000016
EU00100ST10000016
But when the column generated_key containt more than a values, it return 0 rows
CODE
generated_key
EU00100ST10000016
EU00100ST10000016, EU00100ST10000017

If you need to compare to a list, use delimited comparisons
WHERE EXISTS (SELECT 1
FROM list_agg
WHERE ',' || generated_key || ',' LIKE '%,' || code ',%'
)
The "list_agg" name suggests that you are aggregating values from another query. If so, you might be able to use use in with no aggregation. But your question doesn't have enough details to know if that is really the case.

Related

Postreg SQL get All Value with quotes from the comma separated

I have Values which are stored like 1,2,3,4,5 in the database.
I want it back like '1','2','3','4','5'.
I am trying with string_agg(format('''%s''', ticker_information.user_groups), ',')
but giving me result '1,2,3,4,5'
Any solution ? Or let me know If I am doing wrong.
Thanks
Try this if you just want a string back with the quotes
WITH sample AS (
SELECT '1,2,3,4,5'::text as test
)
SELECT
'''' || array_to_string(
string_to_array(test, ','),
''','''
) || ''''
FROM sample
You can create an array from your csv string using unnest, wrap the elements with quote_literal() and then aggregate them again. You can achieve this with a subquery ..
SELECT array_to_string(array_agg(i),',') FROM
(SELECT quote_literal(unnest(string_to_array(user_groups,',')))
FROM ticker_information) j (i);
array_to_string
---------------------
'1','2','3','4','5'
Or with a LATERAL :
SELECT array_to_string(array_agg(quote_literal(j.i)),',')
FROM ticker_information,
LATERAL unnest(string_to_array(user_groups,',')) j (i);
array_to_string
---------------------
'1','2','3','4','5'
Another option would be with regular expressions.. but it could get nasty if the elements of your csv contain commas.
Demo: db<>fiddle

Listagg delimeter is geting printed is there are no values selected

I am using LISTAGG() function in my select statement in a procedure such as
SELECT DISTINCT REPLACE(LISTAGG(a.student1||':'||a.score||'+')
WITHIN GROUP ( ORDER BY a.roll_no) OVER (PARTITION BY a.class)
If my select statement has not null values then i get
for eg: ABC:100
But if the select is empty then i get
for eg: :
I wanted it to be null if there are no rows selected.
The problem is that the expression you're aggregating returns a non-NULL value whether or not the values you're concatenating are NULL. My guess is you want something like
listagg(case when a.student1 is not null
then a.student1||':'||a.score||'+'
else null
end)
If you can have a null value for student1 but a non-NULL value for score, you'd need to adjust the case statement to specify what you want to happen in that case (do you want the ":" and the "+"? Just the "+"?)
Well, your REPLACE is incomplete. Also, is '+' really supposed to be concatenated? What string separates values, then?
REPLACE (
LISTAGG (a.student1 || ':' || a.score, '+') --> removed || for the + sign
WITHIN GROUP (ORDER BY a.roll_no)
OVER (PARTITION BY a.class),
':', '') --> missing arguments for REPLACE
If that's still not what you asked, please, provide sample test data and desired output.

How to give like operator of sql which matches any values given inside brackes seperated by commas and those values can be in any order

I have a column say column Country where when I fire query values come like
|Country|
|US,UK,Canada|
|India,Pak,Bangladesh|
|Israel,Sudan,Africa|
Now when I filter out country using where such as
select * from country where Country = 'US,UK,Canada'
then it gives perfectly fine result like
|US,UK,Canada|
but suppose Country column displays data like
|Country|
|Canada,UK,US|
|India,Pak,Bangladesh|
|Israel,Sudan,Africa|
then above query won't work.
I want a way by which it works when cell values separated by commas to be in any order be it likeCanada,UK,US or US,Canada,UK etc .
I don't know how to handle this using like operator of SQL
Stroring CSV in column is an example of poor design. You should use complex type(array) or normalize your schema.
Workaround using array comparison(assuming all elements in column are unique):
WITH cte AS (
SELECT *, ('{' || country || '}')::text[] AS a_country
FROM Country
)
SELECT *
FROM cte
WHERE a_country <# ('{' || 'Canada,UK,US' || '}')::text[]
AND a_country #> ('{' || 'Canada,UK,US' || '}')::text[];
db<>fiddle demo

How to put together data from different tables without duplicating

Im feeling a bit stupid now but I cant seem to make it happen. I have som tables with data and the problem I have with one SELECT is that the data is sometimes duplicated. (Sorry, English is not my first language, ask if unclear.
SELECT (IM_FAKTUROR.FAKT_NUMMER || ' ' || IM_FAKTURA_GRUPPER.FAKT_TYP) AS 'ProjektNrNamn',
But sometimes those two tables/columns have exactly the same data and in those cases I only want the data from one of them, not both. How to?
If there is different data in the two I want all info.
Use a case expression. If the two columns have the same value, just return one of them. Else return both of them:
SELECT case when IM_FAKTUROR.FAKT_NUMMER = IM_FAKTURA_GRUPPER.FAKT_TYP
then IM_FAKTUROR.FAKT_NUMMER
else (IM_FAKTUROR.FAKT_NUMMER || ' ' || IM_FAKTURA_GRUPPER.FAKT_TYP)
end AS 'ProjektNrNamn',
Try this:
SELECT DISTINCT ProjektNrNamn FROM
(
SELECT (IM_FAKTUROR.FAKT_NUMMER || ' ' || IM_FAKTURA_GRUPPER.FAKT_TYP) AS 'ProjektNrNamn'
) as t
Try SELECT DISTINCT:
SELECT DISTINCT
IM_FAKTUROR.FAKT_NUMMER || ' ' || IM_FAKTURA_GRUPPER.FAKT_TYP AS 'ProjektNrNamn'
FROM ...
But this answer assumes that the project name is the only thing in your select list. If you have other columns, it gets more complicated.

SQL limiting Count function based on IN clause using comma delimited list

I have a table of Matricies (JobMatricies) ID, Desc, DeptIDs
1 Admin (PM) 6,7,138,131,11,9,10,134,135,14,105,129
5 Sales Processing (PM) 92,16,153,17,91,32,26,93,99,18,89,90,155,19
6 Construction Processing (PM) 100,36,20,136,22,88,23,25,34,106,38,39,132,41,42,43,154,152,84
DeptIDs are a Comma Delimited list of departments that I want to use to count how many records are represented by the Matrix.
Normally I would do something like....
select Matrix_ID,
Matrix_Desc,
JobCount = (select count(sched_ID) from JobSchedule where dept_ID in (**92,16,153,17,91,32,26,93,99,18,89,90,155,19**))
from jobMatrices
How do I replace the hard coded delimited string with the ID's stored with each matrix, so that I can produce a list of matricies with their own unique count based on the comma delimited string that is stored with each matrix.
Thanks
I just answered a similar question where the poster wanted to sum the delimited list of numbers in a similar table layout. My solution used CTE's in Oracle to turn that list into a CTE table which would allow you to join against it. I believe that technique would be of use here if your RDBMS supports that. Please have a look: https://stackoverflow.com/a/38231838/2543416
select s.ID
, m."Desc"
from JobSchedule s
, jobMatrices m
where position(',' || s.ID || ',' in ',' || m.DeptIDs || ',')>0;
select m."Desc"
, count(s.ID) JobCount
from JobSchedule s
, jobMatrices m
where position(',' || s.ID || ',' in ',' || m.DeptIDs || ',')>0
group by m."Desc";
In MySQL, you can treat a comma-separated string as a SET, and there's a builtin function FIND_IN_SET() that helps:
select m.Matrix_ID,
m.Matrix_Desc,
(select count(sched_ID) from JobSchedule
where FIND_IN_SET(dept_ID, m.DeptIds)) AS JobCount
from jobMatrices AS m;
This will have terrible performance, however.
If you use some RDBMS other than MySQL, they may have a different solution that works similarly.
You should be specific in your question and tag your question appropriately. You only tagged your question sql, but this is a language used by many RDBMS vendors.