Mysql Natural sorting in varchar field - mysqli

Is there anyway to sort the string with number field by its number only
I have a value like this
subject_code
DE 312
DE 313
DE 315
Eng 311
COMP 314
can it be sort like this
subject_code
Eng 311
DE 312
DE 313
COMP 314
DE 315
I tried
order by SOUNDEX(subject_code),LENGTH(subject_code),subject_code
but it does not work as expected.
Thank you for your any help and suggestions.

One workaround to your situation uses string operations to obtain the numerical subject code and use it for sorting.
SELECT
subject_code
FROM yourTable
ORDER BY
CAST(SUBSTR(subject_code,
INSTR(subject_code, ' ') + 1) AS UNSIGNED)
However, you should really be storing the text and numerical code in separate columns.
Output:
Demo here:
Rextester

Related

how to find non- Ascii key symbols in a string. DB2?

How to find non-ASCII symbols in a string ? (We are using DB2)
We have tried following select statement but it is not working.
SELECT columnname
FROM tablename
WHERE columnname LIKE '%[' + CHAR(127) + '-' + CHAR(255) + ']%'
COLLATE Latin1_General_100_BIN2
I guess you were trying to use CHR() function, instead of CHAR(), which is a data-type.
If you are using a newer db2 version, that has REGEXP functions, you can try using REGEXP_LIKE() function.
Follow an example from samble db:
SELECT EMPNO, LASTNAME FROM EMPLOYEE WHERE REGEXP_LIKE(LASTNAME,'[E-H]')
EMPNO LASTNAME
------ ---------------
000010 HAAS
000020 THOMPSON
000050 GEYER
000060 STERN
000090 HENDERSON
000100 SPENSER
000110 LUCCHESSI
000120 O'CONNELL
000140 NICHOLLS
000170 YOSHIMURA
000180 SCOUTTEN
000190 WALKER
000210 JONES
000230 JEFFERSON
000250 SMITH
000260 JOHNSON
000270 PEREZ
000280 SCHNEIDER
000290 PARKER
000300 SMITH
000310 SETRIGHT
000320 MEHTA
000330 LEE
000340 GOUNOT
200010 HEMMINGER
200220 JOHN
200240 MONTEVERDE
200280 SCHWARTZ
200310 SPRINGER
200330 WONG
30 record(s) selected.
All names selected contains letters from E to H, as specified by the search-pattern.
As I didn't have any row containing such ranges.. I updated one of the rows, adding chars 169 and 174 to it.
Update employee set LASTNAME = ('LEE' || chr(169) || chr(174)) WHERE LASTNAME = 'LEE'
and, using this REGEXP_LIKE function:
SELECT EMPNO, LASTNAME FROM EMPLOYEE WHERE REGEXP_LIKE(LASTNAME , '[' || CHR(127) || '-' || CHR(255) || ']')"
EMPNO LASTNAME
------ ---------------
000330 LEE©®
1 record(s) selected.
Regards

Select one way without return

Working with the professional mobility of insee on more than 1m of entities, i seek to add up a field called ipondi only on the journeys from commune of residence to commune of work, and not of commune of work to residential commune.
Let us assume a simple example, with the column of commune of residence named "departure", and commune of work named "arrival", and the field which i wish to make the sum named "ipondi":
start; end; ipondi
La Ciotat; Marseille; 84
La Ciotat; Marseille; 15
Aubagne; Ceyreste; 12
Marseille; La Ciotat; 73
So I get the following result:
select start, end, sum(ipondi)
from trajets
group by start, end
So I get the following result:
La Ciotat; Marseille; 99
Aubagne; Ceyreste; 12
Marseille; La Ciotat; 73
Which is normal. However, I would like to "delete" the Marseille; La Ciotat because it is the return journey of the first two lines.
This being so to arrive at this result:
start; end; ipondi
La Ciotat; Marseille; 99
Aubagne; Ceyreste; 12
My link to my database : https://drive.google.com/file/d/1TOB1MTAt8UNCjt0up6qcgnR593yMXkqt/view?usp=sharing
How to do this on PostgreSQL?
Thank you.

CASE where a lot of text needs trimming

I have an output in my queries that gives me:
xxxxxxx xxxxxxxxx : 123456 (xx) - xxxxxxx...
or
xxxxxxx xxxxxxxxx : 12345678 (xx) - xxxxxxx...
basically text before either a 6 or 8 digit number then text after.
Ideally I'd like to be able to CASE this column so I'd have an output where it's a 6 digit number = London and the output when it's an 8 digit number = Paris.
But I am very stuck on how to get the CASE statement to achieve this - essentially trim out a lot of text, work out if the number is either 6 or 8 digits long, then tell me if it's London or Paris. I'm not sure if it's possible.
Is this sort of CASE statement achievable? Advise / pointers would be very gratefully received. Thanks very much.
One way to do it is using a common table expression with patindex.
First, create and populate sample table (Please save us this step in your future questions)
DECLARE #T As Table
(
LongText varchar(4000)
)
INSERT INTO #T (LongText) VALUES
('.njauaerigha n uaer gauer 345 gnaehn 123456 (43) smgmshmsrtmh s;s nt;srtn ;nbtugarg '),
('asdfasdfasdf 12345678 (65) asdfag gr 34 6sd 64 fasd fasdfas d fasdfasdf asdf'),
('zxcvzxcvzx34cv zxcvzxcv zxcv zxcv zxcv zcxvz xcv z3 45 xcvzxcz dfg dv df df zfd zdf b 654321 (77)'),
('87654321 (99) n;arng an ; ualerg trhrt srth str sth strh ssth'),
('snhs tgnn ang nu g;arug aegaerlhae s ;5 afnauierhga.ngae489tj 8q3y .sn.5yn b.s n .5hy 5');
Then, the common table expression to get the start index of the 8/6 digit number:
WITH CTE AS
(
SELECT LongText,
PATINDEX('%[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9] ([0-9][0-9])%', LongText) As Long,
PATINDEX('%[0-9][0-9][0-9][0-9][0-9][0-9] ([0-9][0-9])%', LongText) As Short
FROM #T
)
Then, select with a couple of case expressions to extract the number and get the city:
SELECT CASE
WHEN Long > 0 THEN SUBSTRING(LongText, Long, 13)
WHEN Short > 0 THEN SUBSTRING(LongText, Short, 11)
END As Number,
CASE
WHEN Long > 0 THEN 'Paris'
WHEN Short > 0 THEN 'London'
END As City,
LongText
FROM CTE
Results:
Number City LongText
123456 (43) London .njauaerigha n uaer gauer 345 gnaehn 123456 (43) smgmshmsrtmh s;s nt;srtn ;nbtugarg
12345678 (65) Paris asdfasdfasdf 12345678 (65) asdfag gr 34 6sd 64 fasd fasdfas d fasdfasdf asdf
654321 (77) London zxcvzxcvzx34cv zxcvzxcv zxcv zxcv zxcv zcxvz xcv z3 45 xcvzxcz dfg dv df df zfd zdf b 654321 (77)
87654321 (99) Paris 87654321 (99) n;arng an ; ualerg trhrt srth str sth strh ssth
NULL NULL snhs tgnn ang nu g;arug aegaerlhae s ;5 afnauierhga.ngae489tj 8q3y .sn.5yn b.s n .5hy 5

In SAS, how to concatenate multiple rows into 1 by some ID

I have a table like this
org_ID linenr text
811558672 10 Legevirksomhet.
811560782 10 Clavier Classics er et musikkselskap som produserer komposisjoner og
811560782 20 arrangementer av svært høy kvalitet. De kombinerer den klassiske
811560782 30 musikktradisjonen med moderne teknikker og deres kunder spenner fra
811560782 40 individuelle musikere til ensembler, festivalarrangører, konserthus,
811560782 50 kulturinstitusjoner, eventskapere og mediaprodusenter.
811560812 10 Grafisk design, illustrasjon og nærliggende virksomhet.
811561592 10 Sosial- og helsetjenesten. Konsulentvirksomhet: Veiledning til
811561592 20 foreldre, fosterhjem, skole og barnehage.
As you can see, for some org_ID, they appear multiple times because one line of text is not enough for them. When this happens, the linenr shows multiple numbers. Now I want to concatenate multiple lines of text into one when org_ID is the same. How shall I do this? Many thanks in advance.
Use SAS Retain functionality to concatenate the text and only output when an new org_ID is read.
Note: The two IF statements handles the cases of first row and last row; where there is no Previous ID or no Next ID.
Working Code: (Your Input data must be sorted)
data have;
infile datalines dlm=',' dsd;
length org_ID 8. linenr 8. text $200.;
input org_ID linenr text $;
datalines;
811558672,10, "Legevirksomhet."
811560782,10, "Clavier Classics er et musikkselskap som produserer komposisjoner og"
811560782,20, "arrangementer av svært høy kvalitet. De kombinerer den klassiske"
811560782,30, "musikktradisjonen med moderne teknikker og deres kunder spenner fra"
811560782,40, "individuelle musikere til ensembler, festivalarrangører, konserthus,"
811560782,50, "kulturinstitusjoner, eventskapere og mediaprodusenter."
811560812,10, "Grafisk design, illustrasjon og nærliggende virksomhet."
811561592,10, "Sosial- og helsetjenesten. Konsulentvirksomhet: Veiledning til"
811561592,20, "foreldre, fosterhjem, skole og barnehage."
;
run;
data want;
set have nobs=nobs;
retain longtext;
retain id;
if(_N_=1) then do; longtext=text; id=org_ID; end;
else if org_ID ne id then do; output; longtext=text; id=org_ID; end;
else longtext=cats(longtext,text);
if (_N_=nobs) then do; output; end;
keep org_ID longtext;
run;
Output:
org_ID=811560782 longtext=Legevirksomhet.
org_ID=811560812 longtext=Clavier Classics er et musikkselskap som produserer komposisjoner ogarrangementer av svært høy kva
org_ID=811561592 longtext=Grafisk design, illustrasjon og nærliggende virksomhet.
org_ID=811561592 longtext=Sosial- og helsetjenesten. Konsulentvirksomhet: Veiledning tilforeldre, fosterhjem, skole og barneha
A DOW loop can accumulate each line of text in the org_ID group into a final longtext. The longtext should be assigned a specific length in order to prevent truncations that may occur if default lengths are used. You may or may not want a space separator between lines that are concatenated.
data want(keep=org_ID longtext);
do until (last.org_ID);
set have;
by org_ID;
length longtext $2000;
longtext = catx(' ', longtext, text);
end;
run;
If the data is not sorted, but the org_ID rows are contiguous, you can use
by org_ID notsorted;
So what is happening ?
Longtext is a non dataset variable, so it is automatically reset to missing at the top of the data step.
The data step iterates for each row in the group until the last row in the group.
The length of the variable longtext is specified after the set statement so it be the last variable in program data vector (pdv), and thus be the second column of the kept variables.
catx is used accumulate the concatenations of the text data within the group. A space is used to separate the text data parts.
If you do not want the space separator, accumulate using
longtext = cats(longtext, text);

Inserting data in table using UTL

friends i had written a code to upload a data in newemp table using UTL code i given below but i get the error
1 declare
2 EMPNO NUMBER(4);
3 ENAME VARCHAR2(10);
4 JOB VARCHAR2(10);
5 MGR NUMBER(4);
6 HIREDATE DATE;
7 SAL NUMBER(7,2);
8 COMM NUMBER(7,2);
9 DEPTNO NUMBER(2);
10 line varchar2(100);
11 namesfile UTL_FILE.FILE_TYPE;
12 begin
13 namesfile :=UTL_FILE.FOPEN('DIPRJDIR','empdata.txt','R');
14 loop
15 UTL_FILE.GET_LINE(namesfile,EMPNO,4);
16 dbms_output.put_line('EMPNO :' || EMPNO);
17 UTL_FILE.GET_LINE(namesfile,ENAME,10);
18 dbms_output.put_line('ENAME :' || ENAME);
19 UTL_FILE.GET_LINE(namesfile,JOB,9);
20 dbms_output.put_line('JOB :' || JOB);
21 UTL_FILE.GET_LINE(namesfile,MGR,4);
22 dbms_output.put_line('MGR :' || MGR);
23 UTL_FILE.GET_LINE(namesfile,HIREDATE,5);
24 dbms_output.put_line('HIREDATE :' || HIREDATE);
25 UTL_FILE.GET_LINE(namesfile,SAL,9);
26 dbms_output.put_line('SAL :' || SAL);
27 UTL_FILE.GET_LINE(namesfile,COMM,9);
28 dbms_output.put_line('COMM :' || COMM);
29 UTL_FILE.GET_LINE(namesfile,DEPTNO,2);
30 dbms_output.put_line('DEPTNO :' || DEPTNO);
31 insert into newemp values(EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO);
32 end loop;
33 utl_file.fclose(namesfile);
34* end;
SQL> /
EMPNO :7839
ENAME :KING
JOB :PRESIDENT
MGR :0
ERROR
declare
*
ERROR at line 1:
ORA-01843: not a valid month
ORA-06512: at line 23
and my data is in below given format
7839KING PRESIDENT 000017-nov-1981 005000.00 000000.0010 so Please help me
That's because the UTL_FILE.GET_LINE procedure, gets a VARCHAR2 as a second parameter.
If you put something else than a varchar2 oracle tries to implicitly cast it to the right type.
This worked quite well for you with numbers, but with a Date datatype, oracle will use the NLS_DATE_FORMAT which might not meet the format of string in the file.
You can fix it by using a VARCHAR2 in the UTL_FILE.GET_LINE call and then use to_date function to convert it to a date datatype.
But, there is a better way to do this job-
You can use an external table to read the file and then insert-select from it.