how do i divide a sql variable into 2 - plsql

i have a field in sql named as address which is of 80 char.
i want to put this field into 2 fields addr1 and addr2 of 40 char each.
how do i do it.

this is for T-SQL, but it can't be much different for PL/SQL
declare #yourVar varchar(80)
select substring(#yourVar, 1, 40), substring(#yourVar, 40, 40)

for plsql, it's substr(), so select substr(addr, 1, 40) as addr1, substr(addr, 40) as addr2 from ...

I think your schema would be better off if you altered that table to have two columns instead of one. I'd prefer that solution to parsing the current value.

Brute-force chopping the 80-character value at position 40 runs the risk of breaking in the middle of a word. You might want to do the following instead:
Replace all runs of whitespace with a single blank.
Find the last blank at or before position 40.
Place everything before that blank in the first result field.
Place everything after that blank in the second result field.
The exact details of the operations above will depend on what tools are available to you (e.g. SQL only, or reading from one DB and writing to another using a separate program, etc.)
There is the possibility that the 80-character value may be filled in such a way that breaking between "words" will require one of the result values to be more than 40 characters long to avoid truncation.

Related

How to remove leading zeroes from a column in Google Data Studio?

I have a column of store IDs which all have leading zeroes. I.E. 0017 shows rather than 17, 0876 shows rather than 876.
All Store IDs are 4 digits long with these leading zeroes. Is there a way to remove these leading zeroes and therefore leave me with 17 and 876 (as per above).
I imagine this would involve a REGEXP statement but I haven't been able to successfully create one yet.
Create a calculated field using this formula REGEXP_REPLACE(Store ID, r'^\D*0*', '').
Working example here.

Can sqlite-utils convert function select two columns?

I'm using sqlite-utils to load a csv into sqlite which will later be served via Datasette. I have two columns, likes and dislikes. I would like to have a third column, quality-score, by adding likes and dislikes together then dividing likes by the total.
The sqlite-utils convert function should be my best bet, but all I see in the documentation is how to select a single column for conversion.
sqlite-utils convert content.db articles headline 'value.upper()'
From the example given, it looks like convert is followed by the db filename, the table name, then the col you want to operate on. Is it possible to simply add another col name or is there a flag for selecting more than one column to operate on? I would be really surprised if this wasn't possible, I just can't find any documentation to support it.
This isn't a perfect answer as it doesn't resolve whether sqlite-utils supports multiple column selection for transforms, but this is how I solved this particular problem.
Since my quality_score column would just be basic math, I was able to make use of sqlite's Generated Columns. I created a file called quality_score.sql that contained:
ALTER TABLE testtable
ADD COLUMN quality_score GENERATED ALWAYS AS (likes /(likes + dislikes));
and then implemented it by:
$ sqlite3 mydb.db < quality_score.sql
You do need to make sure you are using a compatible version of sqlite, as this only works with version 3.31 or later.
Another consideration is to make sure you are performing math on integers or floats and not text.
Also attempted to create the table with the virtual generated column first then fill it with my data later, but that didn't work in my case - it threw an error that said the number of items provided didn't match the number of columns available. So I just stuck with the ALTER operation after the fact.

Suppress/Filter a row

I am fairly new to using PeopleSoft BI Publisher plugin for MS Word and integrating it with PS Query Manager. My question is whether in the RTF file you can put logic to suppress or filter out data?
I have a for-each grouping that prints a line (row). I would like to add logic to NOT print the line if the Witholding amount field (M.WTHD_AMT) is equal to 0 (zero). My question is what would the syntax look like, and where should I place it (on the For Each grouping below, the Field level, or somewhere else?) I know I can alter the PS Query (data source) to do the filtering but I would like to leave that as-is and handle this in the template.
I see that there is another conditional IF statement ("rmt_") so I'm not sure if I can add this additional logic to that element or if I need a separate one. I appreciate any feedback!
EDIT:
I've added a new "Conditional Region" as suggested, and it works with just the WTHD_AMT criteria !0 to zero, however I tried added additional criteria where L.PYMNT_TYPE = 'R' and when I run the process it doesn't display data on the PDF output. Is there something wrong with the syntax? Do I need to have a separate Conditional Region for this 2nd criteria? I've seen another BI report where they have 2 or 3 criteria as part of one element.
<?if:number(M.WTHD_AMT)!=0.00?> and <?if:L.PYMNT_TYPE='R'?>
Option 1
You can nest <?if?> statements. Just add another <?end if?> at the end. Make sure there are no spaces between the all of the IF or END IF objects at the beginning or end of the content/row, else the row may still be displayed.
Option 2
You can add conditions in the repeating section. Below will repeat the region for every record where M.WTHD_AMT is not 0.00
<?for-each:record_path/record[M.WTHD_AMT!='0.00']?>
'Conditional Region' is the button you are looking for.
When using this button, make sure to double check where the if/endif or C/EC elements are added. It tends to ignore the selected element and join the elements to the start and end of the line. You will then need to cut and paste it into the right spot. For you this will probably be right after the F element and before the E element.

SQLite sorting a column containing numbers or text

I have a column containing user entry descriptions, these descriptions can be anything however i do need them sorted into a logical order.
The text can be anything like
16 to 26 months
40 to 60 months
Literacy
Mathematics
When i order these in sql statement the text items return fine. However any beginning with numbers come back in an order not logical
i.e.
16 to 26 months
will be before
8 to 20 months
i understand why as it takes first character etc but don't know how to alter sql statement (using sqlite) to improve the performance without messing up the entries beginning with text
When i cast to numeric the numbers are fine the items beginning with text go wrong
Thanks
What you need is sorting the values in "natural order". To achieve this you will need to implement your own collating sequence; SQLite doesn't provide one for this case.
There are some questions (and answers) regarding this topic here on SO, but they are for other RDBMS. The best I could find in a quick search was this:
http://wiki.ozanh.com/doku.php?id=python:database:sqlite:how_to_natural_sort
You should think about improving your table schema, e. g. splitting the period into separate integer columns (monthsMin, monthsMax) instead of using text, which would make sorting much easier. You can always build a string from this values if necessary.

SqlLite query a range based on column value

I have a project in SQLite which contains a table
Prefix table
prefix id
T6A-T6Z 1
YAA-YAZ 2
ZAA-ZAZ 3
7RA-7RZ 4
7TA-7YZ 5
For example I have the value “T6C” which falls in the range of the first record. I need the id of that record. I look into REGEXP as a possible solution but what I read I need a callback function This app is being developed in Adobe Air and I could not find a way to implement the callback.
I also tried the wildcard '_' approach but came up short on that.
Any help would be great.
This is a lousy data format. You should really have the beginning and ending values in separate fields. Oh well. You can do this with string manipulations:
select *
from prefix
where 'T6C' between substr(prefix, 1, 3) and substr(prefix, -3, 3)
If your prefix ranges followed the simple pattern of your first four (1-4) example id's, it would be a simple LIKE query using the first two characters of your prefix (range) beginning:
SELECT id FROM table WHERE prefix LIKE 'T6%';
But your fifth (5) example id has a prefix range that spans beyond the expected -7TZ range ending convention that the other four represented. If you have design control of the the prefix ranges then LIKE is another alternative.

Resources