How set LIKE criteria for specific chars in Jet, Access - sql

I have field UPon in my table with following values :
1,15,28
2,17,28
121,217,33
181,17
66,45,1171
988,38
17
For example, I need result for record which contain only 17
Now, if I use UPon LIKE '%17%' then I'll get records bellow:
2,17,28
121,217,33
181,17
66,45,1171
17
But, I need sql query return only records 2,17,28, 181,17and 17
I can't use , in criteria because this char can be anywhere or not be at all.

(making this an answer as it's what you decided to go with and will make it easier for any future readers to find, rather than in the comments)
you could just expand your query to or the 4 cases - i.e. = '17' or like '%,17,%' or like '17,%' or like '%,17'

Related

SQL query find few strings in diferent columns in a table row (restrictive)

I have a table like this one (in a SQL SERVER):
field_name
field_descriptor
tag1
tag2
tag3
tag4
tag5
house
your home
home
house
null
null
null
car
first car
car
wheel
null
null
null
...
...
...
...
...
...
...
I'm developing a WIKI with a searchbar, which should be able to handle a query with more than one string for search. As an user enters a second string (spaced) the query should be able to return results that match restrictively the two strings (if exists) in any column, and so with a three string search.
Easy to do for one string with a simple SELECT with ORs.
Tried in the fronted in JS with libraries like match-sorter but it's heavy with a table with more than 100,000 results and more in the future.
I thought the query should do the heavy work, but maybe there is no simple way doing it.
Thanks in advance!
Tried to do the heavy work with all results in frontend with filtering and other libraries like match-sorter. Works but take several seconds and blocks the front.
Tried to create a simple OR/AND query but the posibilities with 3 search-strings (could be 1, 2 or 3) matching any column to any other possibility is overwhelming.
You can use STRING_SPLIT to get a separate row per search word from the search words string. Then only select rows where all search words have a match.
The query should look like this:
select *
from mytable t
where exists
(
select null
from (select value from string_split(#search, ' ')) search
having min(case when search.value in (t.tag1, t.tag2, t.tag3, t.tag4, t.tag5) then 1 else 0 end) = 1
);
Unfortunately, SQL Server seems to have a flaw (or even a bug) here and reports:
Msg 8124 Level 16 State 1 Line 8
Multiple columns are specified in an aggregated expression containing an outer reference. If an expression being aggregated contains an outer reference, then that outer reference must be the only column referenced in the expression.
Demo: https://dbfiddle.uk/kNL1PVOZ
I don't have more time at hand right now, so you may use this query as a starting point to get the final query.

SQL concat value as column

I'm trying to convert one string to a valid column.
As you can see I need to get something like 'mo._olddb_uid_'+nu._olddb_name_db that should use the column mo._olddb_uid_001
How can I achieve this:
SELECT *
FROM [PI_CONSOLIDATION].[dbo].[new_unite] nu
LEFT JOIN [PI_CONSOLIDATION].[dbo].[Motif_Orientation] mo ON CONCAT('mo._olddb_uid_',nu._olddb_name_db) = CONCAT(nu._olddb_name_db,'_',nu.id_motif_orientation)
WHERE nu.nom_res = 'TEST' and nu.prenom_res = 'Foobar'
Thanks
EDITED:
I have 18 application each with his DB. Those applications are almost similar with different data but sometimes the data can be found on also on the other sources.
So [new_unite] has the id of patient, id_group and the source database
id_resident id_groupe_res _olddb_name_db
728 31 src1
629 21 src6
731 25 src9
934 12 src18
...
The other table has some parameters that have identical params but with different IDs depending on the DB of the source.
So the [Motif_Orientation] looks like :
So mainly this query is just only to test if the data is stored correctly on the final application where there is just one DB and all the data merged
id_motif_orientation label
1407 Famille
1410 Structures d'hébergement
1422 Etablissement d'Education Spéciale
What you could try to do is make a function with the output being the value you want to left join. Your output should be a single value doesn't matter the type. Then, call it as:
LEFT JOIN
(func_name(param1,param2,...) AS CONCAT(...) FROM DUAL)
ON 1=1
The result should be your value left joined to the current table under whatever column name you need. The only problem is that you will need to do this one by one for each row, so it is only really useful for smaller tables. Wish you gave more info so I could give a better answer but this worked for me when I was having a similar issue with renaming a column.

sql query to show a range and account for missing numbers

I have a SQL query
SELECT
Group_Id, MIN(Rec_Number) as RecStart, MAX(Rec_Number) AS RecEnd
FROM
Rec
WHERE
Group_Id != ''
GROUP BY
Group_Id
ORDER BY
Group_Id
This produces the following kind of results.
92-2274 9222740001 9222740004
92-2275 9222750001 9222750026
etc...
However if record 3 is missing (in the first row for instance) the query obviously doesn't account for it. What I am trying to do is the following
92-2274 9222740001 9222740002
92-2274 9222740004 9222740018
92-2275 9222750001 9222750016
92-2275 9222750018 9222750026
etc...
So essentially each time the script sees a record missing inside the group it starts a new line whilst staying inside the group before iterating on the next group. The group_Id is of course the first 6 digits of the rec_Number
I would also like to do this as well
92-2274 0001 0002
92-2274 0003 0004
Or even trim it to and remove the leading 0's as well if possible I know about using Right (Rec_Number, 4) however as this is a float the automatic convert to string seems to be messing something up as I get +009 is many columns so I assume I need to cast first or something. This particular function I could do it Excel after the fact I guess but I'm sure SQL could do it if the guy writing the query was a DBA and not a bumbling server admin (that's me!)
So is there a way of doing that in SQL also I must warn you that the standard CTE or using functions such as row number don't work as this is SQL Server 2000 - yes it is that old!
Hence me struggling to find posts on Stack Overflow that apply. Many of them start with the WITH keyword which means I can't use any of those to start with!
I think I am needing an IF ELse kind of block but I am not sure what kind of method I can use to get the query to create a new row each time it hits a missing concurrent number in the group range.
The final output will show me the ranges of records in each group whilst highlighting the missing ones via a new line each time.
For the second part, this should work :
RIGHT ( CAST ( MIN (Rec_Number) as Decimal(10)), 4)
It will only keep the last 4 characters of your number.

Select query with where clause that requires a range of varchars

Here's the thing, I have a stored procedure which must select products from the database, but only those which fit in between the start product code, and the finish product code which the user chooses and get sent to the procedure.
Now the product codes are varchars, and they may contain numbers AND letters, like 01, 01B and 02A may be product codes, and the procedure must be able to select all the values in between the user selected ranges.
I'm having trouble with such where clause doing it like this:
...
SELECT ...
WHERE ... AND
ProductCode >= #IniProCod
AND
ProductCode <= #FinProCod
...
The available product codes are shown to the user via a previous query which returns only available product codes, so there should be no problem with non existant values.
I also tried evaluating them as text, although they are received as varchars by the procedure anyway, and since this is inside a dynamic SQL query it actually looks something like this:
...
SELECT ...
WHERE ... AND
ProductCode >= '''+#IniProCod+'''
AND
ProductCode <= '''+#FinProCod+''''
...
And when I try to execute it it returns either the first row, or a set of rows that has very little to nothing to do with the actual values I'm sending to the procedure, so I don't even think it's comparing the values as strings at all.
I leave out code that has nothing to do with the issue, the query actually works alright without this range where clause.
So any ideas?
Edit:
I also tried using BETWEEN but got the same outcome.
And I'm very certain it is just not comparing the variables as text even when they are declared as varchars and I'm using apostrophes on them, and this is only happening on this procedure. I tested this same clause on a clean select query and it does behave as it should, comparing each character for what they are. If I set the initial values as 0 and 29 respectively it will give me a range from 01 to 29 which are the values contained within that range, but when these same values are given to the stored procedure it will return a range from 01 which is the first value, to 03F, which makes no sense to me.
Most likely, you'll need to have your application figure out the list of product codes based on the start & end codes, then send that list to the stored procedure. Your SQL would just contain something like AND ProductCode IN (#myProductCodeList).

Splitting text in SQL Server stored procedure

I'm working with a database, where one of the fields I extract is something like:
1-117 3-134 3-133
Each of these number sets represents a different set of data in another table. Taking 1-117 as an example, 1 = equipment ID, and 117 = equipment settings.
I have another table from which I need to extract data based on the previous field. It has two columns that split equipment ID and settings. Essentially, I need a way to go from the queried column 1-117 and run a query to extract data from another table where 1 and 117 are two separate corresponding columns.
So, is there anyway to split this number to run this query?
Also, how would I split those three numbers (1-117 3-134 3-133) into three different query sets?
The tricky part here is that this column can have any number of sets here (such as 1-117 3-133 or 1-117 3-134 3-133 2-131).
I'm creating these queries in a stored procedure as part of a larger document to display the extracted data.
Thanks for any help.
Since you didn't provide the DB vendor, here's two posts that answer this question for SQL Server and Oracle respectively...
T-SQL: Opposite to string concatenation - how to split string into multiple records
Splitting comma separated string in a PL/SQL stored proc
And if you're using some other DBMS, go search for "splitting text ". I can almost guarantee you're not the first one to ask, and there's answers for every DBMS flavor out there.
As you said the format is constant though, you could also do something simpler using a SUBSTRING function.
EDIT in response to OP comment...
Since you're using SQL Server, and you said that these values are always in a consistent format, you can do something as simple as using SUBSTRING to get each part of the value and assign them to T-SQL variables, where you can then use them to do whatever you want, like using them in the predicate of a query.
Assuming that what you said is true about the format always being #-### (exactly 1 digit, a dash, and 3 digits) this is fairly easy.
WITH EquipmentSettings AS (
SELECT
S.*,
Convert(int, Substring(S.AwfulMultivalue, V.Value * 6 - 5, 1) EquipmentID,
Convert(int, Substring(S.AwfulMultivalue, V.Value * 6 - 3, 3) Settings
FROM
SourceTable S
INNER JOIN master.dbo.spt_values V
ON V.Value BETWEEN 1 AND Len(S.AwfulMultivalue) / 6
WHERE
V.type = 'P'
)
SELECT
E.Whatever,
D.Whatever
FROM
EquipmentSettings E
INNER JOIN DestinationTable D
ON E.EquipmentID = D.EquipmentID
AND E.Settings = D.Settings
In SQL Server 2005+ this query will support 1365 values in the string.
If the length of the digits can vary, then it's a little harder. Let me know.
Incase if the sets does not increase by more than 4 then you can use Parsename to retrieve the result
Declare #Num varchar(20)
Set #Num='1-117 3-134 3-133'
select parsename(replace (#Num,' ','.'),3)
Result :- 1-117
Now again use parsename on the same resultset
Select parsename(replace(parsename(replace (#Num,' ','.'),3),'-','.'),1)
Result :- 117
If the there are more than 4 values then use split functions