Merge multiple rows in a single - sql

I need merge multiple rows in a single row with data concatenated on the columns.
This three lines are result is from my query with INNER JOIN
Name | SC | Type
----------------------
name1 | 121212 | type1
name2 | 123456 | null
name3 | null | type1
I want display result like this:
Name | SC | Type
----------------------
name1; 121212; type1;
name2; 123456; ;
name3; ; type1;
It's a single row, each column with data concatenated with ; and a \n in the end of each data.
The final query need run in SQL Server and Oracle.

I honestly doubt you can use the same query in both oracle and SQL-Server since they both have different functions when it comes to dealing with null values.
For Oracle:
SELECT NVL(Name,'') || ';' as name,
NVL(SC,'') || ';' as SC,
NVL(type,'') || ';' as type
FROM (YourQueryHere)
For SQL-Server
SELECT isnull(Name,'') + ';' as name,
isnull(SC,'') + ';' as SC,
isnull(type,'') + ';' as type
FROM (YourQueryHere)
Note that as #jarlh said, in concatenating side you can use concat(value,value2) which should work both on SQL-Server and Oracle, depending on your version.

You could simply concatenate the fields:
SELECT ISNULL(Name,'') + ';' as Name,
ISNULL(SC, '') + ';' as SC,
ISNULL(Type, '') + ';' as Type
FROM
(
-- whatever is your query goes here...
);

Related

SQL query value (more char) longer then actual value in table

I'm trying to query with Postgres a value where my query string (value) has more char than the actual value in the column:
| id | firstName|
|:---| :--------|
| 1 | bee |
| 2 | beeWaxer |
so for example if I query beeWax, because beeWax has bee inside it I would like it to return also bee and also beeWaxer.
if I use a ILIKE operator it will only return beeWaxer (obviously):
SELECT * FROM table WHERE firstName ILIKE '%beeWax%';
is there a query that will return both rows?
It seems you want a LIKEin both directions: Show all names that include the search word and all names that are included in the search word. Something along the lines of:
SELECT *
FROM table
WHERE firstName ILIKE '%' || :searchword || '%'
OR :searchword ILIKE '%' || firstName || '%';
I agree with the existing answer, but if you want a little cleaner code you can also use the case insensitive regex:
SELECT *
FROM table
WHERE firstName ~* 'beeWax' or 'beeWax' ~* firstname
You can check if the firstname is like each row in column firstname
select *
from table x
where exists (
select 1 from table y
where 'beeWax' like '%' || x.firstName || '%'
);

How to search whole words in a string that has delimiter ";"?

I have a column that has values like this 'Blood work;MRI;ICC', which can be a string with some words separated by ';'.
I wonder with a like clause, how can I make a query that returns results that when you search by 'Blood work', 'mri', 'icc' but not by 'blood' or 'mr' or 'ic'?
To search for a field in a CSV list, one method is:
where ';' + mycol + ';' like '%;mri;%'
Demo on DB Fiddle:
with
csv as (select 'Blood work;MRI;ICC' v),
match as (select 'mri' m union all select 'Blood work' union all select 'Blood')
select csv.v, match.m,
case when ';' + csv.v + ';' like '%;' + match.m + ';%'
then 'match'
else 'no match'
end matched
from csv
cross join match
v | m | matched
:----------------- | :--------- | :-------
Blood work;MRI;ICC | mri | match
Blood work;MRI;ICC | Blood work | match
Blood work;MRI;ICC | Blood | no match
I would personally use a string splitter:
SELECT {Columns}
FROM dbo.YourTable YT
CROSS APPLY STRING_SPLIT (YT.YourColumn,';') SS
WHERE SS.[Value] = 'mri';
If you're not using SQL Sevrer 2016+, then you can use a custom splitter, like DelimitedSplit8K_LEAD.

Postgresql select where array overlaps using like

Is it possible to determine if an ARRAY column contains overlapping values from another array with the LIKE clause?
The && operator works but the strings have to be exact matches
q = """select * from articles where keywords && '{"mortgage brokers"}';""" // Exact match
Is it possible to filter the keywords where rows contain values with substring, not the full string? Something like:
q = """select * from articles where keywords && LIKE '{"mortgage"}';""" // HOW TO FILTER keywords containing value with substring
LIKE operates on strings. To check whether two arrays overlap, you can use &&.
From the Array Functions and Operators documentation:
&& : overlap (have elements in common)
SELECT ARRAY[1,4,3] && ARRAY[2,1] arrays_overlap;
| arrays_overlap |
| -------------- |
| true |
To see if there are values in an array that are LIKE those from another array, one solution would be to unnest both arrays and compare the results with LIKE:
SELECT EXISTS (
SELECT 1
FROM
unnest(ARRAY['abc', 'def' ]) my_array(x)
INNER JOIN unnest (ARRAY['a', 'z' ]) my_keywords(x)
ON my_array.x LIKE '%' || my_keywords.x || '%'
) arrays_have_similar_elements;
| arrays_have_similar_elements |
| ---------------------------- |
| true |
SELECT EXISTS (
SELECT 1
FROM
unnest(ARRAY['abc', 'def' ]) my_array(x)
INNER JOIN unnest (ARRAY['y', 'z' ]) my_keywords(x)
ON my_array.x LIKE '%' || my_keywords.x || '%'
) arrays_have_similar_elements;
| arrays_have_similar_elements |
| ---------------------------- |
| false |
Demo on DB Fiddle
Thanks to #GMB for the guidance. I was able to solve the problem using the query below.
SELECT * from articles, unnest(keywords) my_array(x)
INNER JOIN unnest(ARRAY['broker']) my_keywords(x)
ON my_array.x LIKE '%' || my_keywords.x || '%';

Remove additional comma without knowing the length of the string

My tables
MyTable
+----+-------+---------------+
| Id | Title | DependencyIds |
+----+-------+---------------+
DependentIds contains values like 14;77;120.
MyDependentTable
+--------------+------+
| DependencyId | Name |
+--------------+------+
Background
I have to select data from MyTable with every dependency from MyDependentTable separated with a comma.
Expected output:
+---------+-------------------------------------+
| Title | Dependencies |
+---------+-------------------------------------+
| Test | ABC, One-two-three, Some Dependency |
+---------+-------------------------------------+
| Example | ABC |
+---------+-------------------------------------+
My query
SELECT t.Title,
(SELECT ISNULL((
SELECT DISTINCT
(
SELECT dt.Name + '',
CASE WHEN DependencyIds LIKE '%;%' THEN ', ' ELSE '' END AS [text()]
FROM MyDependentTable dt
WHERE dt.DependencyId IN (SELECT Value FROM dbo.fSplitIds(t.DependencyIds, ';'))
ORDER BY dt.DependencyId
FOR XML PATH('')
)), '')) Dependencies
FROM dbo.MyTable t
Problem description
The query works, but adds an additional comma when there are multiple dependencies:
+---------+---------------------------------------+
| Title | Dependencies |
+---------+---------------------------------------+
| Test | ABC, One-two-three, Some Dependency, |
+---------+---------------------------------------+
| Example | ABC |
+---------+---------------------------------------+
I can't use SUBSTRING(ISNULL(... because I can't access the length of the string and therefore I'm not able to set the length of the SUBSTRING.
Is there any possibility to get rid of that unnecessary additional comma?
Normally for group concatenation in Sql Server, people will add leading comma and remove it using STUFF function but even that looks ugly.
Outer Apply method looks neat to do this instead of correlated sub-query. In this method we don't have to wrap the SELECT query with ISNULL or STUFF
SELECT DISTINCT t.title,
Isnull(LEFT(dependencies, Len(dependencies) - 1), '')
Dependencies
FROM dbo.mytable t
OUTER apply (SELECT dt.NAME + ','
FROM mydependenttable dt
WHERE dt.dependencyid IN (SELECT value
FROM
dbo.Fsplitids(t.dependencyids,';'))
ORDER BY dt.dependencyid
FOR xml path('')) ou (dependencies)
Here is the method using STUFF.
SELECT t.Title
,STUFF((SELECT ', ' + CAST(dt.Name AS VARCHAR(10)) [text()]
FROM MyDependentTable dt
WHERE dt.DependencyId IN (SELECT Value FROM dbo.fSplitIds(t.DependencyIds, ';'))
ORDER BY dt.DependencyId
FOR XML PATH(''), TYPE).value('.','NVARCHAR(MAX)'),1,2,' ') Dependencies
FROM dbo.MyTable t

SQL Search string from a column in another column

This may have been been asked before but I am not sure how to search for it.
I want to find if the string in Column2 is a part of , or not used at all in Column1
Column1 | Column2
=======================
ABCDE + JKL | XC
XC - PQ | A
XYZ + A | C
AC + PQ | MA
So the result for column2 never used in column 1 would be
C
MA
The description of the problem talks about the string in column2. YOu can do this with some variation on like. In most databases, some variation of:
select t.*
from t
where t.column1 not like '%' || t.column2 || '%';
Some databases spell || as + or even concat(), but the idea is the same.
However, I'm not sure what the sample data is doing. In no case is the string in column2 in column1.
Seems like another regex expressions task with no regex allowed.
Assuming you have expressions containing only letters, you can write the following query:
CREATE TABLE Expressions
(
Column1 varchar(20),
Column2 varchar(20)
)
INSERT Expressions VALUES
('ABCDE + JKL', 'XC'),
('XC - PQ', 'A'),
('XYZ + A', 'C'),
('AC + PQ', 'MA'),
('A+CF', 'ZZ'),
('BB+ZZ+CF', 'YY')
SELECT E1.Column2
FROM Expressions E1
WHERE NOT EXISTS (
SELECT *
FROM Expressions E2
WHERE E1.Column2=E2.Column1 --Exact match
OR PATINDEX(E1.Column2+'[^A-Z]%', E2.Column1) <> 0 --Starts with
OR PATINDEX('%[^A-Z]'+E1.Column2, E2.Column1) <> 0 --Ends with
OR PATINDEX('%[^A-Z]'+E1.Column2+'[^A-Z]%', E2.Column1) <> 0 --In the middle
)
It returns:
Column2
-------
C
MA
YY