Can you concatenate a variable amount of text in SQL? - sql

I am working with SQL. At my company, we have a table that shows the text that a technician has written while on a service call. However, when the text is saved in a table, IT separates it out by line. In other words, one call text could contain five or more records. I would like to write a query that will show the call number one time and the text that goes with it in one record. The problem is that the call text can be anywhere from 5 to 25 lines / records. Each record has the same call number. Is there a way in SQL to concatenate all the lines of text for one call?

In case you are using SQL server, you can use the following query:
select call_number,
stuff((SELECT distinct ' ' + text_column
FROM Table_Name T2
where T2.call_number = T1.call_number
FOR XML PATH('')),1,1,'')
from Table_Name T1
group by call_number

Try using GROUP_CONCAT
SELECT GROUP_CONCAT(description, '. ') FROM calls WHERE number = '123456';

Related

How to allow parameter to pass blank entry and comma separated multi entry?

I have inherited some code for a query to build a report off of, with a parameter that needs to be able to be left blank and return all rows, take one value and return the value of just that row, and take in multiple values and return all the rows where that value appears.
I am able to set up the query the report is running off of so that I can leave the parameter and blank and return all rows and enter one value and return that one row, or enter one value and return one row and enter multiple comma separated values and return multiple rows, but not both at the same time.
So the code for the relevant part of the query is
create table example as
'~' || (replace(replace(#ParamterNumber, ',' '~'), ' '~)) || '~' as
ParameterNumber;
select * from database d
where (select ParameterNumber from example) like '%' || d.checknumber || '%';
drop table example if exists;
From that, when I enter, for example, '123, 456' as the parameter, it will return the rows where the value is 123, and rows where the value is 456. Similarly, if the parameter is just '123', it returns rows where the value is 123. If the parameter is left blank, it returns no rows. Normally, if I wanted a blank parameter to return all rows, I would have
where d.checknumber like '%' || #ParameterNumber || '%'
, but that won't allow for multiple entries. I'm not sure how to reconcile the two into the same query so that all three conditions (blank, one entry, and multiple entries) can be satisfied.
I can explain the process on how you can achieve that, but not sure If I will be able to write the query very well.
In your procedure which SSRS is using.Using Split string function (if you have) will allow for multiple selection and isnull and nullif condition will make sure that you are getting default value 'Blank' for case where you have nulls or blanks.
where isnull(nullif(d.checknumber,''),'Blank') in (select value from split_string(#ParameterNumber,',')
Then go to your report builder, and while setting up parameters for #ParameterNumber you need to give in this way.
select distinct isnull(nullif(d.checknumber,''),'Blank') ParameterNumber from Yourtablename
give where condition if you want cascading features. This will help you in doing multi select plus blank values.
You could use coalesce function in SSRS as below
select * from database d where d.checknumber like coalesce(Parameter, product)
coalesce docs link here

postgresql - check if a row contains a string without considering spaces

Is it possible to check if a row contains a string without conisdering spaces?
Suppose I have a table like the one above. I want to know if the query column contains a string that may have different consecutive number of space than the one stored or vice versa?
For example: the first row's query is select id, username from postgresql, and the one I want to know if stored in the table is:
select id, username
from postgresql
That is to say the one that I want to know if exists in the table is indented differently and hence has different number of space.
You can use REGEXP_REPLACE; this will likely be very slow on large data set.
SELECT * from table
where REGEXP_REPLACE('select id, username from postgresql ', '\s+$', '') = REGEXP_REPLACE(query, '\s+$', '')
I think you would phrase this as:
where $str ~ replace('select id, username from postgresql', ' ', '[\s]+')
Note: This assumes that your string does not have other regular expression special characters.

Multi-value parameter used with execute(#sql)

I'm having a hard time trying to figure out how to make this work :
I have a big SQL query used for a report, that is run using "execute(#sql)".
Withing #sql I have various select statements that I would like to filter using the values in the multi-value parameter passed from my report #filtervalues.
I've tested the following (this is an example query):
Set #Sql='Select * from my table where field in ('+#filtervalues+')'
When I select a single value in the parameter, the profiler reads it as follows:
Select * from mytable where field in(1234356-1234-1234-1234-123456)
So the selected Guid is without quotes, resulting in "error near 123456"
On the other hand, if I selected several values:
Select * from mytable where field in ('+N'1234456-1231-1234-1244566',N'2345333-3243-2342-2342-23423423'+)
So it adds extra ' and +
Can you help me with this ?
Note:
I cannot use the suggested solution on many websites to apply the filter on the table directly, because this would mess up the data.
Edit:
The multi-value parameter is filled using this query dataset:
select 'No Filter' as fullname,'00000000-0000-0000-0000-000000000000' as systemuserid
union all
select distinct su.fullname, convert(nvarchar(90),su.systemuserid)
from FilteredSystemUser su
I managed to fix this using the following :
1- In my Dataset, instead of passing the parameter as it is, I changed it to :
Join (Parameters!FilterValues.Value," ',' ")
to force the values to be sent as strings, the parameter value is as follows :
1234567','122345','12345
2- In SQL, in my procedure, I added additional ' at the beginning and the end of the parameter to make up for the missing ones. So my code shows the following:
Set #Sql='Select * from my table where field in ('''+#filtervalues+''')'

Check if a value is present in any of the column in the table

I have a table with more than 200 columns. I am populating the table with the help of a text file. The data is getting inserted into the table successfully.
My problem is that I want to check if a particular value from the text file is existing in the table or not. I know that some of you might say that I can check it that you can map the column name from the code and then use the column name and check like this:
select 1 from table_name where column_name like '%value%'
But I dont have the access to the code. I just have the text file and the database.
So I have to check the value in the database only. One way which is tedious and lengthy is to go one by one to each 200 column and then execute like above. Is there any other way?
this will give you a true/false result:
DECLARE #tablexml XML = (SELECT * FROM yourtable FOR XML PATH(''))
SELECT #tablexml.query('//*="valuetosearchfor"')
How about generating 200 odd scripts depending on your table? Below script can be useful
With Sample_CTE as (
select a.TABLE_NAME,b.COLUMN_NAME from INFORMATION_SCHEMA.TABLES a inner join
INFORMATION_SCHEMA.COLUMNS b on a.TABLE_NAME = b.TABLE_NAME and a.TABLE_NAME = 'MYTABLENAME')
SELECT 'SELECT TABLE_NAME,COLUMN_NAME from ' + TABLE_NAME + ' where '+ COLUMN_NAME +' like ''%value%''' from Sample_CTE
What type of file is it? You can use the SQL data importer to import the file to a new table. Once you have the new table you can INNER JOIN on both of the table to compare the data sets.
If I understand this correctly then you have a table with 200 columns. In that table you put some data from a text file, meaning that x number of rows are populated in that table depending on the size of the text file.
Now you want to find a certain value in the table.
If you're not very familiar with SQL you could try a tool like this one:
SQL locator.

How can I run a query on IDs in a string?

I have a table A with this column:
IDS(VARCHAR)
1|56|23
I need to run this query:
select TEST from TEXTS where ID in ( select IDS from A where A.ID = xxx )
TEXTS.ID is an INTEGER. How can I split the string A.IDS into several ints for the join?
Must work on MySQL and Oracle. SQL99 preferred.
First of all, you should not store data like this in a column. You should split that out into a separate table, then you would have a normal join, and not this problem.
Having said that, what you have to do is the following:
Convert the number to a string
Pad it with the | (your separator) character, before it, and after it (I'll tell you why below)
Pad the text you're looking in with the same separator, before and after
Do a LIKE on it
This will run slow!
Here's the SQL that does what you want (assuming all the operators and functions work in your SQL dialect, you don't say what kind of database engine this is):
SELECT
TEXT -- assuming this was misspelt?
FROM
TEXTS -- and this as well?
JOIN A ON
'|' + A.IDS + '|' LIKE '%|' + CONVERT(TEXTS.ID) + '|%'
The reason why you need to pad the two with the separator before and after is this: what if you're looking for the number 5? You need to ensure it wouldn't accidentally fit the 56 number, just because it contained the digit.
Basically, we will do this:
... '|1|56|23|' LIKE '%|56|%'
If there is ever only going to be 1 row in A, it might run faster if you do this (but I am not sure, you would need to measure it):
SELECT
TEXT -- assuming this was misspelt?
FROM
TEXTS -- and this as well?
WHERE
(SELECT '|' + IDS + '|' FROM A) LIKE '%|' + CONVERT(TEXTS.ID) + '|%'
If there are many rows in your TEXTS table, it will be worth the effort to add code to generate the appropriate SQL by first retrieving the values from the A table, construct an appropriate SQL with IN and use that instead:
SELECT
TEXT -- assuming this was misspelt?
FROM
TEXTS -- and this as well?
WHERE
ID IN (1, 56, 23)
This will run much faster since now it can use an index on this query.
If you had A.ID as a column, and the values as separate rows, here's how you would do the query:
SELECT
TEXT -- assuming this was misspelt?
FROM
TEXTS -- and this as well?
INNER JOIN A ON TEXTS.ID = A.ID
This will run slightly slower than the previous one, but in the previous one you have overhead in having to first retrieve A.IDS, build the query, and risk producing a new execution plan that has to be compiled.