Write a query and pass the predefined value - sql

First i write my query....
SELECT V.Country as Country, count(distinct MyNo) as CountData
FROM dbo.details V
WHERE country = 'india'
and (',' + ISNULL(replace(cateId,' ',''),'') + ',' like '%,31,%')
GROUP BY Country
I have a variable like #Id and want to replace like
(',' + ISNULL(replace(cateId,' ',''),'') + ',' like '%,#Id,%')
so any one help me how to do that and in ID i have the value in different record id now we assume is 31 so how to write that query
and thanks in advance.

like '%,' + cast(#Id as varchar(12)) + ',%'
If #Id is a varchar variable, you can omit the cast:
like '%,' + #Id + ',%'

You can also write this as:
(',' + ISNULL(replace(cateId, ' ', ''), '') + ',' like replace('%,#Id,%', '#Id', #id))

Related

Modify/clean field values before applying a query filter in MongoDB like in SQL Server?

I have a SQL Server query that I need to convert into a Mongo Query. As we all know that we can clean up fields in SQL before applying conditions to them e.g
In the 3rd line we are applying ltrim,rtrim on the clinics field before applying the like condition to it. Same with the reverse field in the query multiple times. If this was a single step query I would have done something maybe using aggregation but this is a multistep cleanup using replace, convert, ltrim, rtrim etc in different places.
Can someone please throw some light on how I could convert it. If someone is an expert in this domain and can convert it into Mongo, that would be great as well. Thanks :)
select rule from rules where
isnull(status,0) = '1' AND isnull(deleted,0) = '0'
AND (((ltrim(rtrim(isnull(clinics,'0'))) like '0%') OR
( ',' + replace(replace(isnull(clinics,'0'),' ','') ,' ','') + ','
like '%,' + convert(varchar,"""+category+""") + ',%')) AND
(',' + replace(replace(isnull(clinics,'0'),' ','') ,' ','') + ','
not like '%,-' + replace(convert(varchar,"""+category+"""),' ','') + ',%')) AND
((( (ltrim(rtrim(isnull(reverse,'0'))) like '0%') OR
(( ','+ replace(replace(isnull(reverse,'0'),' ','') ,' ','') + ','
like '%,' + convert(varchar,"""+primary+""") + ',%')))
AND (',' + replace(replace(isnull(reverse,'0'),' ','') ,' ','') + ','
not like '%,-' + replace(convert(varchar,"""+primary+"""),' ','') + ',%') ))

Concat column values with comma as the separator

I am trying to figure out the result of the below query on how to concat all the columns into a single string with comma separated values. The number of values can be dynamic.
SELECT 'Sc4','Sc5','Sc8','Sc7','Sc2'
I want the result to be as below:
Sc4,Sc5,Sc8,Sc7,Sc2
I have tried using stuff but did manage to concat the string but unable to insert comma in between.
Below is what i have tried
SELECT Stuff((SELECT 'Sc4','Sc5','Sc8','Sc7','Sc2' FOR XML PATH('')), 2, 0, '');
UPDATE
I would like to rephrase my question, is there any way the out shown below can be converted to csv
i assume Sc4, Sc5 etc are your column name and not string constant ?
SELECT Stuff(
(
SELECT ',' + Sc4 + ',' + Sc5 + ',' + Sc8 + ',' + Sc7
+ ',' + Sc2
FROM yourtable
FOR XML PATH('')
), 1, 1, '');
Try concatenation like
SELECT 'Sc4' + ',' + 'Sc5' + ',' + 'Sc8' + ',' + 'Sc7' + ',' + 'Sc2'

Add selected values from multi column into one column separated by ','

I want to select values from multiple columns into one column. I have 2 separate columns from which i want to get name,address,state,zip in following format in SQL Server 2008
Name (new line)
address,state,zip
Name (new line)
address,state,zip
Query:
select
name + char(13) + concat(address,',', state,',', zip)
from
tbl1
join
tbl2 on....
I am not able to get the desired output. I get concat is not a recognized built in function name.
You could use + operator and cast the zip field as varchar directly like this:
For example:
select 'Dara Singh' + char(13) + '1234 Main Street' + ',' + 'NY' + ','
+ cast(95825 as varchar(10))
This is how your query would look:
select name + char(13) + [address] + ',' + [state] + ',' + cast([zip] as varchar(10))
from tbl1 join tbl2 on....

Test if a string contains at least 2 words in SQL

I have an sql request like :
SELECT *
FROM table
WHERE lower(title) LIKE lower('%It's a beautiful string i think%')
I need to check if at least 2 words in my string It's a beautiful string i think are contained in my field title... How can i do that ?
For example, if in my field title i have the string I think it's beautiful, This query should return me this object...
Thanks !
You could split your string into a temporary table (say, using something like this: http://ole.michelsen.dk/blog/split-string-to-table-using-transact-sql/) and then do a join, with a count.
You could generate the following SQL statement dynamically:
SELECT title, count(*)
FROM
(
SELECT title
FROM table1
WHERE (' ' + lower(title) + ' ') LIKE lower('% It %')
UNION ALL
SELECT title
FROM table1
WHERE (' ' + lower(title) + ' ') LIKE lower('% s %')
UNION ALL
SELECT title
FROM table1
WHERE (' ' + lower(title) + ' ') LIKE lower('% a %')
UNION ALL
SELECT title
FROM table1
WHERE (' ' + lower(title) + ' ') LIKE lower('% beautiful %')
UNION ALL
SELECT title
FROM table1
WHERE (' ' + lower(title) + ' ') LIKE lower('% string %')
UNION ALL
SELECT title
FROM table1
WHERE (' ' + lower(title) + ' ') LIKE lower('% I %')
UNION ALL
SELECT title
FROM table1
WHERE (' ' + lower(title) + ' ') LIKE lower('% think %')
) AS table2
GROUP BY title
HAVING COUNT(*) >= 2
A stored procedure might be more efficient and you could have the whole job done on the server side.
You could use a function like this
CREATE FUNCTION [dbo].[CheckSentece] (#mainSentence varchar(128), #checkSentence varchar(128))
RETURNS NUMERIC AS
BEGIN
SET #mainSentence=LOWER(#mainSentence)
SET #checkSentence=LOWER(#checkSentence)
DECLARE #pos INT
DECLARE #word varchar(32)
DECLARE #count NUMERIC
SET #count=0
WHILE CHARINDEX(' ', #checkSentence) > 0
BEGIN
SELECT #pos = CHARINDEX(' ', #checkSentence)
SELECT #word = SUBSTRING(#checkSentence, 1, #pos-1)
DECLARE #LEN NUMERIC
//Simple containment check, better to use another charindex loop to check each word from #mainSentence
SET #LEN=(SELECT LEN(REPLACE(#mainSentence,#word,'')))
if (#LEN<LEN(#mainSentence)) SET #count=#count+1
SELECT #checkSentence = SUBSTRING(#checkSentence, #pos+1, LEN(#checkSentence)-#pos)
END
return #count
END
and get the number of words from second sentence contained in the first one

Concatenation of strings by for xml path

Hi!
Today I learned for xml path technique to concatenate strings in mssql. Since I've never worked with xml in mssql and google hasn't helped, I need to ask you.
Let's imagine the default case. We need to concatenate some strings from a table:
declare #xmlRepNames xml = (
select
', [' + report_name + ']'
from (
select distinct
report_order,
report_name
from #report
) x
order by
report_order
for xml path(''), type)
select
stuff((select #xmlRepNames.value('.', 'nvarchar(max)')), 1, 1, '')
So I get smth like this:
[str1], [str2], [strn]
Ok. It works fine. But I have two very similar concatenate blocks. The difference is just in the way the result string looks like:
[str1], [str2], [strn]
and
isnull([str1], 0) as [str1], isnull([str2], 0) as [str2], isnull([strn], 0) as [strn]
So I can write 2 very similar code blocks (already done, btw) with different string constructors or to try extend previous code to has xml variable containing 2 kind of constructors and then concatenate by xml node type. Doing 2nd way I met some problems - I wrote this:
declare #xmlRepNames xml = (
select
', [' + report_name + ']' as name,
', isnull([' + report_name + '], 0) as [' + report_name + ']' as res
from (
select distinct
report_order,
report_name
from #report
) x
order by
report_order
for xml path(''), type)
select
stuff((select #xmlRepNames.value('/name', 'nvarchar(max)')), 1, 1, ''),
stuff((select #xmlRepNames.value('/res', 'nvarchar(max)')), 1, 1, '')
but it raise error "XQuery [value()]: 'value()' requires a singleton (or empty sequence), found operand of type 'xdt:untypedAtomic *'".
To replace, e.g., '/name' to '/name[1]' or any other '/name[x]', will return just x-th 'name' record but not all 'name' records concatenated.
[question]: is it possible to solve problem 2nd way like I want and if it's possible then how?
[disclaimer]: the problem isn't really serious for me now (1st way just a little bit uglier but also fine), but it seems very interesting how to come over :)
Thanks!
Your subquery cannot return two values. If you just want to concatenate strings, you do not need the xml data type at all. You can do the stuff() and subquery in a single statement:
declare #Rep1Names nvarchar(max) = (
stuff((select ', [' + report_name + ']' as name
from (select distinct report_order, report_name
from #report
) x
order by report_order
for xml path('')
)
), 1, 1, '');
declare #Rep2Names nvarchar(max) = (
stuff(select ', isnull([' + report_name + '], 0) as [' + report_name + ']' as res
from (select distinct report_order, report_name
from #report
) x
order by report_order
for xml path('')
)
), 1, 1, '');
Ok, so I haven't been completely satisfied the way Gordon Linoff suggested and since I've found this kind of problem actual for me I'm adding here another solution without using for xml path:
declare
#pivot_sequence nvarchar(max),
#columns_sequence nvarchar(max)
select
#pivot_sequence = coalesce(#pivot_sequence + ', [', '[')
+ col_name + ']',
#columns_sequence = coalesce(#columns_sequence + ', ', '')
+ 'isnull([' + col_name + '], 0) as [' + col_name + ']'
from some_table
order by
/* some_columns if needed to order concatenation */
Obviously, it'll work much slower but in cases when you haven't many rows it won't drastically affect on performance. In my case I have dynamic pivot query and these strings are built for it - I won't have many columns in pivot so it's fine for me.