Wildcard list of numbers after comma and join on single value [closed] - sql

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 months ago.
Improve this question
I have TABLE A with one of the columns containing a single value and TABLE B with one of the columns containing list of possible matching values.
My code seems to take only first items in the list but does not go deeper within a list to find matching number.
Can you please help me to improve the following code:
select Logs.SingleValue,
Instances.list from Logs,Instances
where Logs.Column1=Instances.DeviceNumber and
(',' + RTRIM(Instances.list) + ',') LIKE Logs.SingleValue
The data in the list looks like
106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120
or
3346, 3347, 3348, 3349, 3350, 3351, 3352, 3353, 3354, 3355, 3356, 3357, 3358, 3359, 3360
I use SQL within R programming environment; not sure what version it is. I'm not sure if the DBMS is MS SQL Server or ORACLE. All I know is that I have found a similar case and the command did not work so it needs to be handwritten in pure SQL.

The syntax looks like T-SQL, meaning it's MS SQL Server.
The best advice I can give you is to normalize your database - get rid of that comma-delimited column and move it to a table.
Read Is storing a delimited list in a database column really that bad?, where you will see a lot of reasons why the answer to this question is Absolutely yes!
If you can't do that, you should probably change your current SQL code to something like this:
select Logs.SingleValue, Instances.list
from Logs
inner join Instances ON Logs.Column1 = Instances.DeviceNumber
and (', ' + RTRIM(Instances.slotlist2) + ',') LIKE '%, '+ Logs.Column2 +',%'
This way you should be able to get all the records where slotlist2 has the number in Column2 somewhere in the list.
Note the space after the first comma in both sides of the like operator.
Please also note that I've changed your implicit join to an explicit join.
Since explicit joins have been a part of ANSI SQL for over 25 years now, and every self-respecting RDBMS supports them; there really is no need to use implicit joins anymore.
Edit: I've tested my query, and it seems to be working fine.
You can look at it yourself on rextester.

Result of most recent Query
So as on the screen shot there seems to be the problem with either a Query or a package within an R studio that lets operate SQL on CSV files without the Data Base.
Kind Regards
Dominik
P.S. Orginal post contains renamed column names just to simplify the case I am after solving.

Related

Simple Delete Command in SQL giving error message [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed last year.
Improve this question
I'm fairly new to SQL (I learned it just yesterday). The DBMS application I am using is OpenOffice.org Base on Windows 10.
I created a table in my DBMS by the name of Employees, with several records. The Primary Key is EmployeeID (I'll attach a screenshot of the table for reference).
The problem is when I try to execute a code to delete the record with the EmployeeID "E001", I get an error message.
Code:
DELETE FROM "Employees"
WHERE "EmployeeID" = "E001";
This code seems simple enough to me. However, this is the error message I get:
1: Column not found: E001
I expected this to work, because I tried to use it on the w3schools.com online editor, and it worked (with a different database). I'll leave a link to it down below.
If this problem is exclusive to OOo Base, I can't do anything about it, since I need to use it for a school assignment.
Thanks in advance.
w3schools.com Online Editor
Quotes in a RDBMS are typically used for different purposes, as described in the comments above.
String literal values are always contained in 'single quotes', double quotes are typically needed as delimiters to identify object names where the name contains one of several non-standard characters or clashes with the name of a reserved word.
So double quotes are not necessary when naming a table Employees - but would be if for example the table's name was "order" since order is also a reserved keyword, or "Employee Status" since it contains a space.
Some databases have their own specific delimiters either instead of or an addition to double quotes, such as MySql which uses `backticks` or SQL Server that uses [square brackets].

TSQL Replace rule for: a|2$5.0| to a|5.0|5.0| [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
I have a table with string field like a|2$5.0| and I need to convert it to the following one a|5.0|5.0|.
I'm using SQL Server 2016.
The logic is as follows:
a - is the first character od each string
| - is a list elements separator
$ - if there is a $ sign in string, the element (value between $ and | signs) should be repeated as many times as the value of number preceeding $ sign (in my example 2 times).
String can be also more complex, but the same logic applies, eg.:
a|2$5.0|3.1|-4.2|3$-9.6|
which should be converted to:
a|5.0|5.0|3.1|-4.2|-9.6|-9.6|-9.6|
Any help will be appreciated.
Thanks in advance.
Honestly, like the comment say, I recommend fixing the design. Storing delimited data in your database is a bad idea, if I am honest. T-SQL is also a poor choice here, as it's far from good at string manipulation.
That being said, you can do this. I use DelimitedSplit8K_LEAD here, as it is ordinal position aware. if you're not on a recent version of SQL Server, you'll need to replace STRING_AGG with the old FOR XML PATH method:
SELECT STRING_AGG(NS.NewString,'|') WITHIN GROUP (ORDER BY DS.ItemNumber,T.I) + '|' AS NewString
FROM (VALUES('a|2$5.0|3.1|-4.2|3$-9.6|'))V(YourString)
CROSS APPLY dbo.DelimitedSplit8K_LEAD(V.YourString,'|') DS
CROSS APPLY (VALUES(CHARINDEX('$',DS.Item)))CI(I)
CROSS APPLY (VALUES(ISNULL(LEFT(DS.Item,NULLIF(CI.I,0)-1),1)))R(I)
CROSS APPLY (VALUES(STUFF(DS.Item,1,CI.I,'')))NS(NewString)
JOIN (VALUES(1),(2),(3),(4),(5),(6),(7),(8),(9),(10))T(I) ON R.I >= T.I;

Why does SQL want you to select the column and THEN refer to the table? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
So this isn't a technical question, but rather questioning why a language is designed the way it is.
I've been learning SQL and one thing that's been bothering me greatly is how SQL asks you to name the column you want and THEN name the table you want to get it from. To me, it would make more sense that you refer to the parent body (which is the table) and THEN the column it has. But SQL seems to forces users to do it the other way around. Why?
I'm just curious as to why the language is designed this way.
SELECT column
FROM table
why not
FROM table
SELECT column
SQL tries to mimic English language to some extent, so that it feels natural to formulate the query.
In spoken English you would say something like "I want the names of the employees". You would not say "I want of the employees their names" or something like that.
But you are right, it might have been a good idea to have the query represent the order of execution. And "From the employee table I want the names" would not be so far off the mark :-)
SQL is a descriptive language, not a procedural language. It describes the result set being produced. And, you can think of that result set as a report, with column headers.
As such, the basic querying construct returns those column headers. The rest of the query describes how they are produced.
You may find this post useful. Starting with FROM is the most logical way to think about a query (Why would anyone write SELECT before knowing what to SELECT from?). However, SQL guidelines were designed as if your query were a command. Thus, you are commanding the system to SELECT the data for you, and the FROM further specifies that command.
Of course, the actual execution is distinct from the lexical and logical orders above.

Select first_name where last_name has as second letter 'o'? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I'm using Oracle, this information comes from the "HR.EMPLOYEES" table, but I don't know how to structure that query.
There are several ways to achieve your goal. In no particular order:
Using SUBSTR
Just use SUBSTR. This function allow you to extract a part from a string:
SELECT first_name FROM table WHERE SUBSTR(last_name, 2, 1) = 'o'
Remember, you are only filtering the rows based on lower case as 'o' which is not same as upper case 'O'. And, you need to create a function-based index on the column too, to avoid any performance issues due to FTS.
If you have only one column for the name, then use SUBSTR and INSTR in the SELECT to get the first_name. I would like to leave this up to you. Let me know if you really struggle with INSTR. A hint for you to try and learn yourself, INSTR( string, substring [, start_position [, nth_appearance ] ] )
Using regular expression
The same could be achieved using REGEXP_LIKE, however, it would be much resource consuming:
SELECT first_name FROM table WHERE REGEXP_LIKE(last_name, '^.o')
Here, I am looking for a string such as:
^ after the start of the string
. I have any character
o then an o
Using LIKE pattern matching
This solution is rather database-vendor agnostic: it will work with (almost?) any RDBMS:
SELECT first_name FROM table WHERE last_name LIKE '_o%'
Pattern matching is more or less like the wildcard you might use in your shell. Except than is SQL _ is used for any character and % is used for any string (incl. empty string).
Other
By searching through the web and in various Oracle's documentation you might probably be able to find several other -- more or less exotic -- options.
For example, one might think of using a virtual column on the second letter of last_name.
Or, if and only if, you need case insensitive approach, you can have a look at this demo http://lalitkumarb.wordpress.com/2014/01/22/oracle-case-insensitive-sorts-compares/. Please make sure you have utmost understanding about the trivial aspects as mentioned above, before jumping onto complex things.

Overcoming the reserved word "IN" in sql server [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions concerning problems with code you've written must describe the specific problem — and include valid code to reproduce it — in the question itself. See SSCCE.org for guidance.
Closed 9 years ago.
Improve this question
Just for reference I am using SQL Azure.
I noticed when I am trying to select data from a table based on a license plate and the state of that plate I get no results back if the state is "IN". I realize the word "IN" is reserved in SQL server; however, I am containing that within quotes in my query. I currently am in testing phase and have only one record in the table which has a lisence plate 287YGB and state IN.
If I write my query as follows I get nothing back.
SELECT MakeModel, CitizenID, VehicleID FROM tblVehicles WHERE tblVehicles.Lisence = '287YGB' AND tblVehicles.PlateState = 'IN'
If I write my query this way I get back my result. But this is not good enough.
SELECT MakeModel, CitizenID, VehicleID FROM tblVehicles WHERE tblVehicles.Lisence = '287YGB'
And finally, if I write my query this way I get the only row in the table.
SELECT MakeModel, CitizenID, VehicleID FROM tblVehicles
From these tests I can see that the last where parameter is causing the problem. I am assuming it is due to the fact that the word "IN" is reserved. Is there a way around this?
Reserved words usually only cause problems if you're using them as field names, and in that case you need to wrap them with brackets ("[]") to eliminate the problem. I will amost guarantee you that your PlateState has some garbage in it, so you need to either trim it first (LTRIM(RTRIM(PlateState)) = 'IN') or use Like '%IN%' instead, and this will return the results you expect.
try this
SELECT MakeModel, CitizenID, VehicleID FROM tblVehicles WHERE tblVehicles.Lisence = '287YGB' AND LTRIM(RTRIM(tblVehicles.PlateState)) = 'IN'