How to detect whether column NVARCHAR contains Latin or Cyrillic chars - sql

I have "Template" table:
CREATE TABLE Template (
ID BIGINT, -- PK
NAME NVARCHAR(255)
)
Column NAME contains russian or english text. How can I move value of this column to RUSSIAN_NAME and ENGLISH_NAME columns in depends on value of NAME column value.
CREATE TABLE Template (
ID BIGINT, -- PK
RUSSIAN_NAME NVARCHAR(255),
ENGLISH_NAME NVARCHAR(255)
)

Try this:
I have no idea what the russian text is meaning, just copied from somewhere
DECLARE #tbl TABLE (name NVARCHAR(255),plainLatin NVARCHAR(255),foreignChars NVARCHAR(100));
INSERT INTO #tbl(name) VALUES
(N'abcd'),(N'слов в тексте'),(N'one more'),(N'с пробелами и без них');
UPDATE #tbl
SET plainLatin=CASE WHEN PATINDEX('%[^-a-zA-Z0-9 ]%' /*add signs you want to allow*/,name)=0 THEN name END
,foreignChars=CASE WHEN PATINDEX('%[^-a-zA-Z0-9 ]%' /*add signs you want to allow*/,name)>0 THEN name END
SELECT * FROM #tbl
The result
+-----------------------+------------+-----------------------+
| name | plainLatin | foreignChars |
+-----------------------+------------+-----------------------+
| abcd | abcd | NULL |
+-----------------------+------------+-----------------------+
| слов в тексте | NULL | слов в тексте |
+-----------------------+------------+-----------------------+
| one more | one more | NULL |
+-----------------------+------------+-----------------------+
| с пробелами и без них | NULL | с пробелами и без них |
+-----------------------+------------+-----------------------+

Related

How to take values from a column and assign them to other columns

Here's what I have:
DECLARE #keyString2 nvarchar(500)
SET #keyString2 =
(SELECT TOP (1) Key_analysis
FROM testing.dbo.[nameWIthoutSpecialChars])
IF CHARINDEX('Limit of Insurance Relativity Factors' , #keyString2) > 0
EXEC sp_rename 'testing.dbo.nameWIthoutSpecialChars.Key2',
'Limit of Insurance Relativity Factors',
'COLUMN';
Basically what I'm doing with that code is renaming column names
with values that are from a different column. Though, if you see, there's a hardcoded string in CHARINDEX, I'd have to already know what's inside of that variable which makes it a real manual process. I could essentially just hardcode the EXEC and run it over and over without even needing the IF statement.
What I'm trying to accomplish is to rename columns based off of values inside of another.
To make it more clear I have a table like this:
+--------------------------------+---------+---------+
| Description | Column2 | Column3 |
+--------------------------------+---------+---------+
| string value 1, string value2 | | |
+--------------------------------+---------+---------+
| string value 1, string value2 | | |
+--------------------------------+---------+---------+
| string value 1, string value 2 | | |
+--------------------------------+---------+---------+
The values in the "Description" column will be the same throughout the table. What I want to have happen is that those values replace the other columns like so
+--------------------------------+----------------+----------------+
| Description | string value 1 | string value 2 |
+--------------------------------+----------------+----------------+
| string value 1, string value2 | | |
+--------------------------------+----------------+----------------+
| string value 1, string value2 | | |
+--------------------------------+----------------+----------------+
| string value 1, string value 2 | | |
+--------------------------------+----------------+----------------+
The only other caveat here is that there may be more or less string values than the 2 shown, I want to run this through multiple tables. Every table has 10 columns that are just like "Column1" and "Column2" in the example, meaning 10 potential columns that need to be renamed considering how many values are in the "Description" column
Experimental table,I didn't use #temporary table or table variable.
create TABLE bbbb (
Description VARCHAR(30) NOT NULL
,column2 VARCHAR(30)
,column3 VARCHAR(30)
);
INSERT INTO bbbb(Description,column2,column3) VALUES
('string value 1,string value2',NULL,NULL),
('string value 1,string value2',NULL,NULL),
('string value 1,string value2',NULL,NULL);
final query
declare #a varchar(100);
declare #b varchar(100);
set #a=(select distinct PARSENAME(REPLACE(Description,',','.'),1) from bbbb)
set #b=(select distinct PARSENAME(REPLACE(Description,',','.'),2) from bbbb)
EXEC sp_rename '[bbbb].[column2]', #a, 'COLUMN';
EXEC sp_rename '[bbbb].[column3]', #b, 'COLUMN';
select * from bbbb

How to use selected value as table name for another select in PostgreSQL

I have table with two coloms source_name and output_name:
CREATE TABLE all_table(
source_name text,
target_name text
);
Source name it is some external data name. Target name it is auto-generated table name in my DB. There is a relationship between the source name and the target name, there is only one target name for each source name.
I have additional table in DB:
CREATE TABLE output_table_1(
first_name text,
second_name text,
birthday timestamp
);
CREATE TABLE output_table_2(
login text,
money int
);
In table "all_table" I have some rows:
| source_name | target_name |
|---------------|----------------|
| personal data | output_table_1 |
| login data | output_table_2 |
I want select information from correct table by source name. So I tried
WITH selected_table AS (
SELECT target_name FROM all_table WHERE source_name='personal data'
)
SELECT * FROM selected_table;
And also
SELECT first_name FROM
(SELECT target_name FROM all_table WHERE source_name='personal data') AS out_table;
But Postgres print me only correct target name
| target_name |
|----------------|
| output_table_1 |
I want to get something similar on my query
| first_name | second_name | birthday |
|------------|-------------|----------|
| FName1 | SName1 | Date1 |
| FName2 | SName2 | Date2 |
| FName3 | SName3 | Date3 |
| FName4 | SName4 | Date4 |
| ... | ... | ... |
I've also tried this query
DO
$$
BEGIN
EXECUTE format('SELECT * FROM %s LIMIT 10', (SELECT target_name FROM all_table WHERE source_name='personal data'));
END;
$$ LANGUAGE plpgsql;
Query executed but nothing happened.
Surfing on Google doesn't do anything useful. But mb I'm bad in this.
¯\(ツ)/¯
if you want to obtain data from DO block you need to define cursor for query.
do
$$
declare
_query text ;
_cursor CONSTANT refcursor :='_cursor';
begin
_query:='Select * from '||(Select tab_name from ... where ..);
open _cursor for execute _query;
end;
$$;
fetch all from _cursor;

how to create a table that inherits from another table in SQL 3?

i have this table salle that has 2 attributes
this is the table that inherits from salle, it's called salleCours and has 3 additional attributes.
when i run the second command in oracle 11g express in sql command line it says under 'under' : missing or invalid option.
i dont know if it's a syntax problem or something else
Create table salle(
Numero varchar(20) primary key,
Videoprojecteur char(1) ) ;
Create table salleCours UNDER salle(
Capacite number(3),
Retroprojecteur char(1),
micro char(1)) ;
You want to define an OBJECT type and then use an object-defined table:
CREATE TYPE salle_type AS OBJECT(
Numero varchar(20),
Videoprojecteur char(1)
) NOT FINAL;
CREATE TYPE salleCours_type UNDER salle_type(
Capacite number(3),
Retroprojecteur char(1),
micro char(1)
);
CREATE TABLE salle OF salle_type (
Numero PRIMARY KEY
);
Then you can insert rows of either type:
INSERT INTO salle VALUES( salle_type( 'abc', 'Y' ) );
INSERT INTO salle VALUES( salleCours_type( 'def', 'Y', 42, 'N', 'X' ) );
And, if you want the values:
SELECT s.*,
TREAT( VALUE(s) AS salleCours_type ).Capacite AS capacite,
TREAT( VALUE(s) AS salleCours_type ).Retroprojecteur AS Retroprojecteur,
TREAT( VALUE(s) AS salleCours_type ).micro AS micro
FROM salle s
Which outputs:
NUMERO | VIDEOPROJECTEUR | CAPACITE | RETROPROJECTEUR | MICRO
:----- | :-------------- | -------: | :-------------- | :----
abc | Y | null | null | null
def | Y | 42 | N | X
db<>fiddle here

SQL Find String

I would like to know if finding a string can be done from another table. It's a bit complicated.
Here's the table: (tbl_dishes)
| dish | Type |
| egg, hotdog & bread | Breakfast |
From the table above, I want to get the individual descriptions of the column dish from another table
2nd Table (tbl_Foods)
| food | Description |
| egg | Fresh |
| hotdog | red |
| bread | toasted |
| steak | meat |
Let's say my query would look like this: (but it's wrong)
SELECT food, description FROM tbl_Foods
WHERE food Exists IN (SELECT dish FROM tbl_Dishes)
My desired results would be:
| food | Description |
| egg | Fresh |
| hotdog | red |
| bread | toasted |
It's like getting all matched word in the dish column. I don't know if it's possible. Please help.
Thank you.
SELECT food, description
FROM tbl_Foods
join tbl_Dishes
on tbl_Dishes.dish like ('%' + tbl_Foods.food +'%')
You will need to split the list
DECLARE #DelimString VARCHAR(100)
SET DelimString = SELECT REPLACE(REPLACE(dish,'&',','),' ', '') FROM tbl_Dishes
DECLARE #Dish TABLE (Dish VARCHAR(50)); INSERT INTO #Dish SELECT CAST(ParamValue AS VARCHAR) FROM MultiValueParams_String(#DelimString)
Use this function.
Create function [dbo].[MultiValueParams_String] (#ParamList varchar(4000))
returns #Values table (RoNum INT,ParamValue varchar(4000))
as
begin
declare #Delim char(1) = ',' -- comma is always the delimiter
declare #Chrind int = 1
declare #Piece nvarchar(50)
declare #RoNum int = 0
while #Chrind>0
begin
select #Chrind=charindex(#Delim,#ParamList)
if #Chrind>0
select #Piece=left(#ParamList,#chrind-1)
else
select #Piece=#ParamList
insert #values(RoNum,ParamValue) values (#RoNum,#Piece)
select #ParamList = right(#ParamList,len(#ParamList)-#chrind)
if len(#ParamList)=0 break
SELECT #RoNum = #RoNum + 1
end
return
end
SELECT food, description
FROM tbl_Foods f
INNER JOIN #Dish d ON f.food = d.dish
Something like this.

improve database table design depending on a value of a type in a column

I have the following:
1. A table "patients" where I store patients data.
2. A table "tests" where I store data of tests done to each patient.
Now the problem comes as I have 2 types of tests "tests_1" and "tests_2"
So for each test done to particular patient I store the type and id of the type of test:
CREATE TABLE IF NOT EXISTS patients
(
id_patient INTEGER PRIMARY KEY,
name_patient VARCHAR(30) NOT NULL,
sex_patient VARCHAR(6) NOT NULL,
date_patient DATE
);
INSERT INTO patients values
(1,'Joe', 'Male' ,'2000-01-23');
INSERT INTO patients values
(2,'Marge','Female','1950-11-25');
INSERT INTO patients values
(3,'Diana','Female','1985-08-13');
INSERT INTO patients values
(4,'Laura','Female','1984-12-29');
CREATE TABLE IF NOT EXISTS tests
(
id_test INTEGER PRIMARY KEY,
id_patient INTEGER,
type_test VARCHAR(15) NOT NULL,
id_type_test INTEGER,
date_test DATE,
FOREIGN KEY (id_patient) REFERENCES patients(id_patient)
);
INSERT INTO tests values
(1,4,'test_1',10,'2004-05-29');
INSERT INTO tests values
(2,4,'test_2',45,'2005-01-29');
INSERT INTO tests values
(3,4,'test_2',55,'2006-04-12');
CREATE TABLE IF NOT EXISTS tests_1
(
id_test_1 INTEGER PRIMARY KEY,
id_patient INTEGER,
data1 REAL,
data2 REAL,
data3 REAL,
data4 REAL,
data5 REAL,
FOREIGN KEY (id_patient) REFERENCES patients(id_patient)
);
INSERT INTO tests_1 values
(10,4,100.7,1.8,10.89,20.04,5.29);
CREATE TABLE IF NOT EXISTS tests_2
(
id_test_2 INTEGER PRIMARY KEY,
id_patient INTEGER,
data1 REAL,
data2 REAL,
data3 REAL,
FOREIGN KEY (id_patient) REFERENCES patients(id_patient)
);
INSERT INTO tests_2 values
(45,4,10.07,18.9,1.8);
INSERT INTO tests_2 values
(55,4,17.6,1.8,18.89);
Now I think this approach is redundant or not to good...
So I would like to improve queries like
select * from tests WHERE id_patient=4;
select * from tests_1 WHERE id_patient=4;
select * from tests_2 WHERE id_patient=4;
Is there a better approach?
In this example I have 1 test of type tests_1 and 2 tests of type tests_2 for patient with id=4.
Here is a fiddle
Add a table testtype (id_test,name_test) and use it an FK to the id_type_test field in the tests table. Do not create seperate tables for test_1 and test_2
It depends on the requirement
For OLTP I would do something like the following
STAFF:
ID | FORENAME | SURNAME | DATE_OF_BIRTH | JOB_TITLE | ...
-------------------------------------------------------------
1 | harry | potter | 2001-01-01 | consultant | ...
2 | ron | weasley | 2001-02-01 | pathologist | ...
PATIENT:
ID | FORENAME | SURNAME | DATE_OF_BIRTH | ...
-----------------------------------------------
1 | hermiony | granger | 2013-01-01 | ...
TEST_TYPE:
ID | CATEGORY | NAME | DESCRIPTION | ...
--------------------------------------------------------
1 | haematology | abg | arterial blood gasses | ...
REQUEST:
ID | TEST_TYPE_ID | PATIENT_ID | DATE_REQUESTED | REQUESTED_BY | ...
----------------------------------------------------------------------
1 | 1 | 1 | 2013-01-02 | 1 | ...
RESULT_TYPE:
ID | TEST_TYPE_ID | NAME | UNIT | ...
---------------------------------------
1 | 1 | co2 | kPa | ...
2 | 1 | o2 | kPa | ...
RESULT:
ID | REQUEST_ID | RESULT_TYPE_ID | DATE_RESULTED | RESULTED_BY | RESULT | ...
-------------------------------------------------------------------------------
1 | 1 | 1 | 2013-01-02 | 2 | 5 | ...
2 | 1 | 2 | 2013-01-02 | 2 | 5 | ...
A concern I have with the above is with the unit of the test result, these can sometimes (not often) change. It may be better to place the unit un the result table.
Also consider breaking these into the major test categories as my understanding is they can be quite different e.g. histopathology and xrays are not resulted in the similar ways as haematology and microbiology are.
For OLAP I would combine request and result into one table adding derived columns such as REQUEST_TO_RESULT_MINS and make a single dimension from RESULT_TYPE and TEST_TYPE etc.
You can do this in a few ways. without knowing all the different type of cases you need to deal with.
The simplest would be 5 tables
Patients (like you described it)
Tests (like you described it)
TestType (like Declan_K suggested)
TestResultCode
TestResults
TestRsultCode describe each value that is stored for each test. TestResults is a pivoted table that can store any number of test-results per test,:
Create table TestResultCode
(
idTestResultCode int
, Code varchar(10)
, Description varchar(200)
, DataType int -- 1= Real, 2 = Varchar, 3 = int, etc.
);
Create Table TestResults
(
idPatent int -- FK
, idTest int -- FK
, idTestType int -- FK
, idTestResultCode int -- FK
, ResultsI real
, ResultsV varchar(100)
, Resultsb int
, Created datetime
)
so, basically you can fit the results you wanted to add into the tables "tests_1" and "tests_2" and any other tests you can think of.
The application reading this table, can load each test and all its values. Of course the application needs to know how to deal with each case, but you can store any type of test in this structure.