Microsoft Access string parsing - ms-access

In MS Access 2003, I have the following values in a column
0-0-60
20-0-0-24S
20.5-0-0-24S
32-0-0
How can I write my query such that I can pull the 3rd item from the column, example the "60" from "0-0-60". Keep in mind that I've optionally got the 4th column also.

You will want to generalize this function for the delimiter and what position, but:
Public Function SplitString(inputString As String) As String
Dim TestArray() As String
TestArray = Split(inputString, "-")
Debug.Print TestArray(2)
SplitString = TestArray(2)
End Function
You can call in in your query like this:
SELECT SplitString([MyField]) AS Expr1
FROM MyTable;
Good Luck!

Will you ever have less than 3 items in each column ?
Really if you've got a very specific format of either 3 decimals or 4 decimals as values, I'd consider changing your schema to
Value1 decimal
Value2 decimal
Value3 decimal
Value4 decimal (NULLABLE)
but that's a little beside the point...
If you really are stuck with this, then its probably quicker to parse in your code, than it is to do some nasty left/right/instr work in the Access SQL Query

The fact you are finding it non-trivial to query you data column is what we call a 'smell'.
This looks exactly like a First Normal Form (1NF) violation because you have non-scalar data in a single column. I trust you are splitting these values for a one-time data scrubbing exercise to fix the problem once and for all (in which case I'd personally use Excel's text to columns feature if the resultset was small).
If you are proposing to do this in a query for you application then I suggest you research normalization and change you schema accordingly.

I believe an inline expression like this on the query builder tool would do the job (untested).
right(yourColumnNam, inStrRev(yourColumnName, '-'))

Related

Integer values considered by VB.Net datatable as decimals after MySQL query

In VB (Winforms) I am extracting statistics from MySQL database and the resulting datatable is used to build different charts. What made me impression is that depending on MySQL query in some cases pure integer values are considered as decimals in datatable and thus my charts look strange with their grid lines depicted with fractions of 1. Examples are below.
When I use in my query grouing the result is not what I expect. Query looks like following:
select Cell,Time,
sum(counter12) as counter
from h_cell
where cell='ABC' and time>='2018-05-26' and time<='2018-06-01'
group by Cell,Time
In this case the datatype of datatable's column 'counter' is 'System.Decimal'. I need to stress that the value is always integer. Also I cannot avoid grouing in my query. The problem is that my chart looks not right with grid lines showing values less than one.
When I design my query without grouping then datatype of the column in datatable is 'System.Int32' and then chart looks as it should.
select Cell,Time,
(counter12) as counter
from h_cell
where cell='ABC' and time>='2018-05-26' and time<='2018-06-01'
Is there a way to avoid this inconsistency?
You might want to take a look at the table structure in MySQL and refer to this page for the equivalent to see why you might be getting a Decimal type: Visual Basic / MySQL Datatypes
Something else you might try (as someone else suggested) is to cast to the data type you are expecting. The only difference is that I would not cast your column, but the result of your sum as follows:
select Cell,Time,
Cast(sum(counter12) As SIGNED) as counter
from h_cell
where cell='ABC' and time>='2018-05-26' and time<='2018-06-01'
group by Cell,Time

MYSQL REGEXP with JSON array

I have an JSON string stored in the database and I need to SQL COUNT based on the WHERE condition that is in the JSON string. I need it to work on the MYSQL 5.5.
The only solution that I found and could work is to use the REGEXP function in the SQL query.
Here is my JSON string stored in the custom_data column:
{"language_display":["1","2","3"],"quantity":1500,"meta_display:":["1","2","3"]}
https://regex101.com/r/G8gfzj/1
I now need to create a SQL sentence:
SELECT COUNT(..) WHERE custom_data REGEXP '[HELP_HERE]'
The condition that I look for is that the language_display has to be either 1, 2 or 3... or whatever value I will define when I create the SQL sentence.
So far I came here with the REGEX expression, but it does not work:
(?:\"language_display\":\[(?:"1")\])
Where 1 is replaced with the value that I look for. I could in general look also for "1" (with quotes), but it will also be found in the meta_display array, that will have different values.
I am not good with REGEX! Any suggestions?
I used the following regex to get matches on your test string
\"language_display\":\[(:?\"[0-9]\"\,)*?\"3\"(:?\,\"[0-9]\")*?\]
https://regex101.com/ is a free online regex tester, it seems to work great. Start small and work big.
Sorry it doesn't work for you. It must be failing on the non greedy '*?' perhaps try without the '?'
Have a look at how to serialize this data, with an eye to serializing the language display fields.
How to store a list in a column of a database table
Even if you were to get your idea working it will be slow as fvck. Better off to process through each row once and generate something more easily searched via sql. Even a field containing the comma separated list would be better.

TSQL select a string, repeated N times

I am looking for a way, inside a TSQL SELECT statement, to repeat a string literal N times, where N is in integer that I select (or calculate) from columns on a table.
What I am doing, specifically, is parsing a hierarchical tree structure into nested HTML unordered lists. So, suppose we're very deep in the tree, but the next entry is very shallow. We need to close a bunch of open <ul> and <li> tags from higher up in the tree. So what I have done (but I feel is too kludgy) is:
select case Depth-Next_Depth
when -1 then ''
when 0 then ''
when 1 then '</ul></li>'
when 2 then '</ul></li></ul></li>'
when 3 then '</ul></li></ul></li></ul></li>'
...
end
from MyTable
I know that I could create a scalar function like ReturnClosingTags(#N int) but I don't want to add another object to the database for this. I want it to all happen in the select statement so I don't have to further modify the DB schema.
I also know that my whole approach here (writing the code myself to parse my tree into HTML) may be harebrained, so feel free to comment with an alternative... but I am interested in the question for its own sake, so even if you say "duh just use .NET library XYZ for this" I'd like to know if there's an answer to this little SQL puzzle.
SQL Server happens to have this function built-in: replicate().
select replicate('</ul></li>', depth)
Because it returns the same type as the first argument, you might want to cast() the value to varchar(8000) or varchar(max) first.

How to store a String (length > 255) from a query?

I'm using Access 2000 and I have a query like this:
SELECT function(field1) AS Results FROM mytable;
I need to export the results as a text file.
The problem is:
function(field1) returns a fairly long string (more than 255 char) that cannot be entirely stored in the Results field created from this query.
When i export this query as a text file, i can't see the string entirely. (truncated)
Is it possible to cast function(field1) so it returns a Memo type field containing the string ?
Something like this:
SELECT (MEMO)function(field1) AS Results FROM mytable;
Do you know others solutions?
There is an official microsoft support page on this problem:
ACC2000: Exported Query Expression Truncated at 255 Characters
They recommend that you append the expression data to a table that has a memo field, and export it from there. It's kinda an ugly solution, but you cannot cast parameters to types in MS Access, so it might be the best option available.
i don't know how to do quite what you're hoping (which makes sense) but a possible alternative could be to create 2 or 3 fields (or separate queries) and extract different portions of the text into each then concat after retrieved.
pseudo: concat((chars 1-255) & (chars 256-510) & (chars 511-etc...))
edit: it's odd that a string longer than 255 is stored but it's not memo. what's up there? another alternative, if you have access to the db, is change the field type. (backup the db first!)

How do I get SSIS Data Flow to put '0.00' in a flat file?

I have an SSIS package with a Data Flow that takes an ADO.NET data source (just a small table), executes a select * query, and outputs the query results to a flat file (I've also tried just pulling the whole table and not using a SQL select).
The problem is that the data source pulls a column that is a Money datatype, and if the value is not zero, it comes into the text flat file just fine (like '123.45'), but when the value is zero, it shows up in the destination flat file as '.00'. I need to know how to get the leading zero back into the flat file.
I've tried various datatypes for the output (in the Flat File Connection Manager), including currency and string, but this seems to have no effect.
I've tried a case statement in my select, like this:
CASE WHEN columnValue = 0 THEN
'0.00'
ELSE
columnValue
END
(still results in '.00')
I've tried variations on that like this:
CASE WHEN columnValue = 0 THEN
convert(decimal(12,2), '0.00')
ELSE
convert(decimal(12,2), columnValue)
END
(Still results in '.00')
and:
CASE WHEN columnValue = 0 THEN
convert(money, '0.00')
ELSE
convert(money, columnValue)
END
(results in '.0000000000000000000')
This silly little issue is killin' me. Can anybody tell me how to get a zero Money datatype database value into a flat file as '0.00'?
I was having the exact same issue, and soo's answer worked for me. I sent my data into a derived column transform (in the Data Flow Transform toolbox). I added the derived column as a new column of data type Unicode String ([DT_WSTR]), and used the following expression:
Price < 1 ? "0" + (DT_WSTR,6)Price : (DT_WSTR,6)Price
I hope that helps!
Could you use a Derived Column to change the format of the value? Did you try that?
I used the advanced editor to change the column from double-precision float to decimal and then set the Scale to 2:
Since you are exporting to text file, just export data preformatted.
You can do it in the query or create a derived column, whatever you are more comfortable with.
I chose to make the column 15 characters wide. If you import into a system that expects numbers those zeros should be ignored...so why not just standardize the field length?
A simple solution in SQL is as follows:
select
cast(0.00 as money) as col1
,cast(0.00 as numeric(18,2)) as col2
,right('000000000000000' + cast( 0.00 as varchar(10)), 15) as col3
go
col1 col2 col3
--------------------- -------------------- ---------------
.0000 .00 000000000000.00
Simply replace '0.00' with your column name and don't forget to add the FROM table_name, etc..
It is good to use derived column and need to check the condition as well
pricecheck <=0 ? "0" + (DT_WSTR,10)pricecheck : (DT_WSTR,10)pricecheck
or alternative way is to use vb script
Ultimately what I ended up doing was using the FORMAT() function.
CAST(FORMAT(balance, '0000000000.0000') AS varchar(30)) AS "balance"
This does have some significant CPU performance impact (often at least an order of magnitude) due to the way SQL Server implements that function, but nothing worked easier, more correctly, or more consistently for me. I was working with less than 100,000 rows and the package executes no more than once an hour. Going from 100ms to 1000ms just wasn't a big deal in my situation.
The FORMAT() function returns an nvarchar(4000) by default, so I also cast it back to a varchar of appropriate size since my output file needed to be in Windows-1252 encoding. Transcoding text is much more obnoxious in SSIS than it has any right to be.