How to get mapping data in oracle - sql

I have two tables in oracle as per below and need mapping data from these two tables from stored procedure or in c# code for .net core. Both will work for me.
First Table contains data which is in key-value form where "Key" is the ID of the Second Table. Value is the actual data required.
First table :
ID Data
1 {"f100000":["02/02/2012"],"f100001":["01/04/2013"]}
So, "f100000", "f100001"... etc are the keys and ID for Second table
Second table has simple data with ID and Name
ID Name
f100000 Name of the field
f100001 Name of the field2
I would expect the result will be as per below:
Key Value
Name of the field 02/02/2012
Name of the field2 01/04/2013

This is not going to happen in current form without extraneous code which is redundant/inefficient when database design could be improved.
Can the design of table 1 not be improved i.e. have separate fields for f###### values and for the corresponding date.
That way the f###### values can be indexed so that joins will run efficiently between the two tables.
This amendment would need to be made in the code which inserts records into table.
If not, you would have to:
Select rows from table1.
Split the string into array based on ',' character
Split of each of these array values into another 2 dimension array based on ':' character when looping through first array
Strip out '[', ']' and '"' characters from date field for it to be parseable
As looping through, then SELECT from table_2.id = value from second array[0] value
Print out results line by line
As this would need to be done each time code is run, it is very efficient. Much better to redesign table 1 and add in logic to insert as required.

Related

SQL Server match partial text in the comma separated varchar column

I have a VARCHAR column category_text in the table that contain tags to a notification stored. I have three tags Query, Complaint and Suggestion and column can have one or more values separated by comma. I am applying a filter and filter can have one or more values as well in comma separated pattern.
Now what I want is to retrieve all the rows that contain at least one tag based on the filter user is applying, for instance user can select 'query,suggestion' as a filter and result would be all the rows that contain one of the tags i.e. query or suggestion.
select
t.category_text
from
real_time_notifications t
where
charindex('query, suggestion, complaints', t.category_text) > 0
order by
t.id desc
Create a new table, like user_category (user.id link to user table, category) and create an index on both. It will speed up a lot for searching and ease your future maintenance a lot.
If you still persist to do that, create an inline function to split string to records and then merge to test.

Get fields from one column to another in Access

Below i have a table where i need to get fields from one column to three columns.
This is how i would like the data to end up
Column1
Music
Column2
com.sec.android.app.music
Column3
com.sec.android.app.music.MusicActionTabActivity
Give the table a numeric autonumber id
Remove the rows with no data with a select where blank spaces or null
Find records with no point in the content with a select
Use the previous query as a source and use the id to find the id + 1 to find the next record and do the same with + 2 to find the second row
Build a table to hold the new structure and use the query as a source to insert the new created data in the new table with the 3 columns structure.
This is an example using sql server
Test table design
Data in table
Query
Look at the query from the inside. The first query inside clean the null records. Then the second query find the records with out point. This records are the reference to find the related two records. Then the id of the records with out point are used to make a query in the select adding 1 for the next record and then other query adding 2 to find the other record. Now you only need to create a table to insert this data, using this query as the source.

SQL Server : selecting row with column that contains multiple comma delimited values

I have a table (a) that contains imported data, and one of the values in that table needs to be joined to another table (b) based on that value. In table b, sometimes that value is in a comma separated list, and it is stored as a varchar. This is the first time I have dealt with a database column that contains multiple pieces of data. I didn't design it, and I don't believe it can be changed, although, I believe it should be changed.
For example:
Table a:
column_1
12345
67890
24680
13579
Table b:
column_1
12345,24680
24680,67890
13579
13579,24680
So I am trying to join these table together, based on this number and 2 others, but when I run my query, I'm only getting the one that contain 13579, and none of the rest.
Any ideas how to accomplish this?
Storing lists as a comma delimited data structure is a sign of bad design, particularly when storing ids, which are presumably an integer in their native format.
Sometimes, this is necessary. Here is a method:
select *
from a join
b
on ','+b.column_1+',' like '%,'+cast(a.column_1 as varchar(255))+',%'
This will not perform particularly well, because the query will not take advantage of any indexes.
The idea is to put the delimiter (,) at the beginning and end of b.column_1. Every value in the column then has a comma before and after. Then, you can search for the match in a.column_1 with commas appended. The commas ensure that 10 does not match 100.
If possible, you should consider an alternative way to represent the data. If you know there are at most two values, you might consider having two columns in a. In general, though, you would have a "join" table, with a separate row for each pair.

Sorting table data issue

I've quite bulky data in a Database table and I want to sort the data based on their ID (Primary Key). The data in the key column could be:
001/2011,
002/2011,
001/2012
When I use 'order by id' it sorts the rows like
001/2011,
001/2012,
002/2011
However, what I am looking for is
001/2011,
002/2011,
001/2012
The data type of the id column is varchar(50). Is there a special SQL function that I should use to sort such type of data?
ORDER BY RIGHT(ID,4)+LEFT(ID,3)
This rearranges the varchar data so that the year comes first and the sequence/month/day-of-year comes after.
If you have some other format to your data, then think along the same lines. Shift the string around using SUBSTRING, of which LEFT and RIGHT are just 2 specific versions.

Constructing an SQL query

I am using SQL and PL/SQL.
I have a table with a single column "name". The data in this column is a semicolon separated string. I want to count the number of elements in each row.
For example, if there are two rows in the table, one with the string 'smith;black;tiger'and one with the string 'x;y', I want the result of the query to be 3 for the first row and 2 for the second row.
How can I write a SQL query that will count the number of elements in a separated list of values?
Your question is very hard to understand, but I think you are saying that you have a table with a column "name", and inside that column, each cell contains multiple values separated by semicolons. You want to count the number of semicolon-separated values in each row.
The PLSQL string functions could help you here, but really you are talking about writing program code to do this task (this isn't normally the job for a database query language). For example, you could use this trick to count the number of semicolons, and then add one:
LENGTH(name) - LENGTH(TRANSLATE(name,'x;','x')) + 1
But the point #Johan is making is that this is a bad way to structure your data. For example, it makes it impossible to lookup by name properly. You can't say where name == "smith", because the name doesn't equal "smith", it equals "smith;black;tiger". You'll have to do a substring search, saying where name like "smith", and that will be inefficient and wrong. What if I ask to look up the name "smi"? You'll say where name like "smi" which will incorrectly find that result -- there is no way to say that "smith" is in the table but "smi" is not, because both are substrings of "smith;black;tiger".
A much better solution, if you want an entry to have multiple names, is to give the entry a unique ID; say 123. (You can ask SQL to automatically generate unique IDs for table rows.) Then, have a separate table for names which maps back onto that row. So say you gave the "smith;black;tiger" row the ID 123 and the "x;y" row the ID 124. Now you would have another table NameMap with two columns:
name | entry
------------------
smith | 123
black | 123
tiger | 123
x | 124
y | 124
Now you can look up names in that table and map them onto the name entries table with a join.
And you'll be able to answer your question: "how many names correspond to each row of the entry table" with a GROUP BY statement like this:
SELECT name, count(*) as value_count FROM NameMap GROUP BY name
You can hack this using this code
SQL code horror
SELECT name
,(LENGTH(COALESCE(vals,''))
- LENGTH(TRANSLATE(COALESCE(vals,''), ';',''))) + 1 AS value_count
FROM table1
ORDER BY name
Remarks
CSV in a database is a very bad anti-pattern.
VALUES is a reserved word, it's a bad idea to name a column after a reserved word.