I've imported data into SQL developer and I need to separate data from one column into a new column. For example I have:
Temp_Title
Congo (1995)
Nadja (1993)
I need to remove the year from the title into a new column named temp_year. I was told that I can use "Parse" but I'm not sure where to start. Any help is greatly appreciated.
You didn't specify database you use; also, you mentioned "SQL Developer" (designed by Oracle) but tagged the question with "plsqldeveloper" tag so - actual query might depend on certain info you didn't share with us.
Anyway, to get you started, here's an example (based on Oracle) which uses two options:
the first one uses traditional SUBSTR + INSTR combination
another one uses regular expressions
.
SQL> with test (temp_title) as
2 (select 'Congo (1995)' from dual union all
3 select 'Nadja (1993)' from dual union all
4 select 'Back to the future (1985)' from dual
5 )
6 select
7 substr(temp_title, 1, instr(temp_title, '(') - 1) title,
8 substr(temp_title, instr(temp_title, '(') + 1, 4) year,
9 --
10 regexp_substr(temp_title, '(\w| )+') title2,
11 rtrim(regexp_substr(temp_title, '\d+\)$'), ')') year2
12 from test;
TITLE YEAR TITLE2 YEAR2
-------------------- ---------------- -------------------- -----
Congo 1995 Congo 1995
Nadja 1993 Nadja 1993
Back to the future 1985 Back to the future 1985
SQL>
Related
Please see the SQLFiddle example:
http://sqlfiddle.com/#!4/abd6d/1
here are a few example address:
MINNEAPOLIS MN 55450
MINNAPOLIS MN 55439-8136
BETHANY OK 73008
Hillsboro Oregon 97124
Not all of them are separated by spaces, but enough that I I think that is the method I want to approach.
running Oracle 11g
update:
this was how it was accomplished:
select bill_address4, Substr(bill_address4, 1, Instr(bill_address4,
',') - 1) "CITY EXMP ONE",
regexp_substr(bill_address4,'[^,]+', 1, 1) "CITY EXMP TWO",
Trim(regexp_substr(bill_address4,'[^,]+', 1, 2)) "STATE/ZIP",
TRIM(regexp_substr(Trim(regexp_substr(bill_address4,'[^,]+', 1,
2)),'[^ ]+', 1, 1)) "STATE",
TRIM(TRIM(regexp_substr(Trim(regexp_substr(bill_address4,'[^,]+',
1, 2)),'[^ ]+',1,2))||'
'||TRIM(regexp_substr(Trim(regexp_substr(bill_address4,'[^,]+', 1,
2)),'[^ ]+',1,3))||'
'||TRIM(regexp_substr(Trim(regexp_substr(bill_address4,'[^,]+', 1,
2)),'[^ ]+',1,4))) "ZIP" from so_header
I do not think this is easily feasible by sql. You will need to rearrange the raw data and the table schema by adding more columns.
The appraoch I recommand is string manipulation by using other programming language, for example, C#.
See if such an approach helps.
TEMP CTE finds position of the first digit in citystatezip column
zip: that's the substring that starts from the zip_position
state: nested functions
substr selects everything up to the zip_position (e.g. "SNOHOMISH WA ")
trim removes trailing spaces
regexp_substr extracts the last word from that substring (e.g. "WA")
city: substring from the 1st character, up to position of the second space character starting from the back of the string (see instr's parameters)
For sample data you posted (LA added), that would look as follows:
SQL> with temp as
2 (select p.*,
3 regexp_instr(citystatezip, '\d') zip_position
4 from po_header p
5 )
6 select t.po_number, t.customer, t.citystatezip,
7 substr(t.citystatezip, t.zip_position) zip,
8 regexp_substr(trim(substr(t.citystatezip, 1, t.zip_position - 1)), '\w+$') state,
9 trim(substr(t.citystatezip, 1, instr(t.citystatezip, ' ', -1, 2))) city
10 from temp t;
PO_NUMBER CUSTOME CITYSTATEZIP ZIP STATE CITY
---------- ------- ------------------------------ ---------- ---------- -----------
1 John SNOHOMISH WA 98290 98290 WA SNOHOMISH
2 Jen MINNAPOLIS MN 55439-8136 55439-8136 MN MINNAPOLIS
3 Jillian BETHANY OK 73008 73008 OK BETHANY
4 Jordan Hillsboro Oregon 97124 97124 Oregon Hillsboro
5 Scott Los Angeles CA 12345 12345 CA Los Angeles
SQL>
Is it perfect? Certainly not, but the final solution depends on much more sample data. Generally speaking, data model is just wrong - you should have split those information into separate columns in the first place.
Let's say that I have a view with the following structure (and sample data):
Sample_Name Sample_Date Sample_ID
John 01-01-2015 453
Jacob 10-10-2016 777
Jingle 11-11-2017 888
Heimer 12-12-2018 999
Schmidt 07-07-2019 333
If someone specifies the year (i.e. '2019'), I want to return that year and the year prior to it. So the following data set would return:
Sample_Name Sample_Date Sample_ID
Heimer 12-12-2018 999
Schmidt 07-07-2019 333
Is there any way for me to create the view with input parameters (similar to a function), where the user can specify what date they are looking for? Wen the date is specified, the view should return data from that year and the year prior to it. I know with functions you can do something similar but according to my google search, this isn't possible in Oracle :(
It doesn't make sense.
A view is just a stored query. If you want to fetch certain data from it, use a where clause, e.g.
select sample_name, sample_date, sample_id
from your_view
where extract (year from sample_date) >= :par_year - 1;
(where you'd enter 2019 into :par_year, when prompted) (: might need to be replaced by &, depending on a tool you use).
I am investigating the benefits of Oracle Text search, and currently am looking at collecting search text data from multiple (related) tables and storing the data in the smaller table in a 1-to-many relationship.
Consider these 2 simple tables, house and inhabitants, and there are NEVER any uninhabited houses:
HOUSE
ID Address Search_Text
1 44 Some Road
2 31 Letsby Avenue
3 18 Moon Crescent
INHABITANT
ID House Name Nickname
1 1 Jane Doe Janey
2 1 John Doe JD
3 2 Jo Smythe Smithy
4 2 Percy Plum PC
5 3 Apollo Lander Moony
I want to to write SQL that updates the HOUSE.Search_Text column with text from INHABITANT. Now because this is a 1-to-many, the SQL needs to collate the data in INHABITANT for each matching row in house, and then combine the data (comma separated) and update the Search_Text field.
Once done, the Oracle Text search index on HOUSE.Search_Text will return me HOUSEs that match the search criteria, and I can look up INHABITANTs accordingly.
Of course, this is a very simplified example, I want to pick up data from many columns and Full Text Search across fields in both tables.
With the help of a colleague we've got:
select id, ADDRESS||'; '||Names||'; '||Nicknames as Search_Text
from house left join(
SELECT distinct house_id,
LISTAGG(NAME, ', ') WITHIN GROUP (ORDER BY NAME) OVER (PARTITION BY house_id) as Names,
LISTAGG(NICKNAME, ', ') WITHIN GROUP (ORDER BY NICKNAME) OVER (PARTITION BY house_id) as Nicknames
FROM INHABITANT)
i on house.id = i.house_id;
which returns:
1 44 Some Road; Jane Doe, John Doe; JD, Janey
2 31 Letsby Avenue; Jo Smythe, Percy Plum; PC, Smithy
3 18 Moon Crescent; Apollo Lander; Moony
Some questions:
Is this an efficient query to return this data? I'm slightly
concerned about the distinct.
Is this the right way to use Oracle Text search across multiple text fields?
How to update House.Search_Text with the results above? I think I need a correlated subquery, but can't quite work it out.
Would it be more efficient to create a new table containing House_ID and Search_Text only, rather than update House?
I have a column containing values like this, example:
Farari - Made in 2013
Mercedes - Made in 2012
Jaguar - Made in 1978
I want to return the car with the highest or recent make year:
Something like this will give me the year but obviously will truncate the rest of the string:
SELECT
MAX(RIGHT(CarProfile, 4))
FROM mySchema.Car;
How do I get the highest year but maintain the full string?
In this case: Farari - Made in 2013
SELECT top 1 *
FROM Car order by RIGHT(CarProfile, 4)*1 desc
SELECT *
FROM Car
WHERE RIGHT(CarProfile, 4) =
(SELECT MAX(RIGHT(CarProfile, 4))
FROM Car)
SQLFiddle Demo
You should normalize your table properly. My ssugested schema would be adding a column for a year and have index it so that it would have great query performance .
SQLFiddle Demo
Sql below for reference:
select CarProfile
from FROM mySchema.Car
where substr(CarProfile, CarProfile.length - 4, CarProfile.length) =
SELECT MAX(RIGHT(CarProfile, 4)) FROM mySchema.Car;
You should get the 'made in' when you print it out, not stored in the database. So instead your table will be:
CarProfile | Year
---------------
Ferrari | 2013
Mercedes | 2012
Jaguar | 1978
And your 'made in' will either be retrieved via the query like so:
SELECT CarProfile, ' - made in', year
FROM Car
HAVING year = MAX(year)
Or you can just write it when it is displayed (for example php):
<?php echo $CarProfile . " - made in " $year;?>
It will make your table much more compact and friendly
My question is made of 3 parts.
First part:
Is there a way to generate rows based on a value?
E.g:
I want to give each family a number of vouchers based on their family_members_count.
Each voucher should have a unique id:
Base table:
id name family_members_count
1 fadi 2
2 sami 3
3 ali 1
Result:
family_id name voucher_id
1 fadi 121
1 fadi 122
2 sami 123
2 sami 124
2 sami 125
3 ali 126
Second part:
Can I control the voucher_id composite key? I want the voucher_id to be like this
(location)(cycle)(sequence 5 digits)
If north = 08 and we are in the second cycle it should be:
080200001
080200002
... and so on.
Third part:
I need the solution in both MS Access 2010 SQL and PostgreSQL 9.1 SQL.
Question 1
Use generate_series(). (In the coming version 9.3 look for the key word LATERAL.)
SELECT id AS family_id
,name
,120 + generate_series(1, family_members_count) AS voucher_id
FROM fam;
-> sqlfiddle demo
Question 2
SELECT id AS family_id
,name
,location
|| to_char(cycle, 'FM00')
|| to_char(generate_series(1, family_members_count), 'FM00000')
AS voucher_id
FROM fam2;
-> sqlfiddle demo
Note the use of to_char() to format numbers as text - and in particular the use of the FM pattern modifier to avoid leading white space.
Question 3
Sorry, I got MS Access out of my system 10 years ago and never looked back. Somebody else might fill in. I doubt it will be as simple.