Why is this join not working in Oracle SQL - sql

I am trying to output everything for table one where there is a mention like something from table two
table one is the aoldataleak from 2006 and table two is a created table of all contestants in a horse race at that time period
select query,
PFERDENAME
from AOLDATA.querydata,
Pferde
where query like ( '%' ||PFERDENAME||'%')
ORDER BY PFERDENAME;
Pferdename is a column in table 2 and query is a column in table one
both are chars and the output I get is just a blank table, but I know for a fact there are querys in the first table that are like Pferdenamen in the second one.
I tried this same statement with a dummy table with only a few entries and there it worked just fine

So here's error cause:
Pferdename CHAR (25) PRIMARY KEY
CHAR datatype right-pads values with spaces up to the max column length. So, if horse name is "Max", Oracle stores it as "Max" followed by 22 spaces (which alltogether make 3 + 22 = 25 characters).
You shouldn't
use CHAR in such a case; use VARCHAR2 instead
name is not the best choice for a primary key; it means that there can't be two horses whose names are "Max"
If it must be CHAR, then you'd better trim it, e.g.
select query, PFERDENAME
from AOLDATA.querydata, Pferde
where query like ( '%' || trim(PFERDENAME) ||'%')
ORDER BY PFERDENAME;
Example:
SQL> with
2 querydata (query) as
3 (select 'This is Max, my favorite horse' from dual),
4 pferde (pferdename) as
5 (select 'Max ' from dual)
6 select query, pferdename
7 from querydata, pferde
8 where query like ( '%' || trim(pferdename) ||'%')
9 order by pferdename;
QUERY PFERDENAME
------------------------------ -----------
This is Max, my favorite horse Max
SQL>

Related

MS Access 2019 - SQL alias on a column converts data to uppercase

I have a strange situation ...
I have a Table with autoincrement field, a number field and a Short Text field all created with default properties
There are only 10 rows in the table and the first 5 rows look like this:
If I run the this query
SELECT Top 5 CustomerID, RegNo, TRIM(RegNo) AS xx
FROM Workordersxx
I get the following:
... as you would expect.
But if I change the query to
SELECT Top 5 CustomerID, RegNo, TRIM(RegNo) AS xxx
FROM Workordersxx
(Note the alias is now "xxx"), I get this:
... with the aliased column now in uppercase.
For clarity, I changed the SQL to show all columns and all rows.
SELECT WorkorderID, CustomerID, RegNo, TRIM(RegNo) AS xxx
FROM Workordersxx
Note that there are no indexes on this table
What am I missing here?

How to find the largest value in a table using SQL?

I am trying to determine the largest value of any data in an entire table using SQL. Note that I really mean an entire table, not just one column or row. The entire table is type varchar, and the goal is to determine what the largest value is (varchar 255, varchar 100, etc).
Example:
Name | ID
John | 1
Jake | 2
James | 3
Should return "James" because it is the largest value in the whole table. I also want the length.
Since all columns are varchar, you could UNPIVOT the table into one column, and then select the TOP 1 value ordered by LEN() DESC.
Note that if the columns have different lengths, you will need to cast them to all have the same length so they can be unpivoted together.
You can get byte size by using
select max(datalength(col0)+datalength(col1)+datalength(col2)...) from table
Be wary this might be an expensive query
You would have to write the query for one particular table:
select top(1) value
from
(
select datalength(col1) as len, cast(col1 as varchar(max)) as value from mytable
union all
select datalength(col2) as len, cast(col2 as varchar(max)) as value from mytable
union all
...
) data
order by len desc;
Look up the internet for data types and how much byte they take For example int = 4 byte.
If you have types like varchar or nvarchar
use max(len(column))+2 the length will give you the byte it's basicly the same

how to increase character sequence in sql if given random number of table rows?

I'm currently studying SQL language in Oracle.
After making very simple STUDENT table, I thought about how to make character sequence in ID field.
For example, if STUDENT table has 6 rows, I want the ID field to be inserted by 'a','b','c'...'f' characters respectively. And another condition is that the ID sequence should be ordered by age in ascending order.
The below explanation is about STUDENT table description and current inserted value (ID field is currently empty).
NAME AGE GRADE ID
hi 15 1
dui 12 2
giyu 16 3
hero 27 4
power 55 3
rai 37 4
///////////////////////////////////////////////////////////////////////////////////////////////////////
DESC STUDENT
NAME VARCHAR2(20)
AGE NUMBER(5)
GRADE NUMBER
ID VARCHAR2(12)
I hope many brilliant ideas come up here =)
until now, this is very easy to come up with making table ordered by age.
but inserting character sequence respectively is ... well .. idea doesn't come up now. And this is not homework. i just want to practice sql language.
update tableX X
set ID=(
select ID from (
select rowid as rid,
chr(mod((row_number() over (order by age))-1,26)+97) as ID
from tableX T
)
where rid=X.rowid
)
Required order of the ID set in the over(order by ) clause. Function row_number() gets sequence number of rows in given order. mod() gets remainder of the division (for 26 chars only). chr() get char by the ascii code.

Update a table foreign keys by substituting by a lookup from the result of another table

Suppose I have two tables :
Table 1:
SELECT * FROM ORIGINAL_DEALER;
ID ENAME
----- --------------------------
1 JOHN
2 00000JOHN
3 JACK
4 00000JACK
5 MARIA
6 00000MARIA
Table 2:
SELECT * FROM NAMES;
ID_NUM
------
1
2
3
4
5
6
I'll have to update NAMES.
Table ORIGINAL_DEALER has duplicate / invalid names such as
00000JOHN
The invalid names have exactly five zeros prefixed before the valid names. i.e valid name: JOHN
invalid name: 00000JOHN
Now I'll have to select the ID's of invalid names from
ORIGINAL_DEALER table and update the ID_NUM in NAMES table
WITH VALID ID. i.e when the invalid ename= '00000JOHN' has an ID
= 2 which is also invalid. but original_dealer is parent table, i'll have to replace all the invalid id's in NAMES table with valid
ones.
i.e the output after updating NAMES should be:
SELECT * FROM NAMES;
ID_NUM
------
1
1
3
3
5
5
How can I do it without manually setting it everytime as there will huge data?
I'm using Oracle DB
You can use a update statement with a lookup like below, by using an inner lookup subquery which in turn uses the TRIM function to strip out the leading zeroes during matching. We also restrict the update to just those Names linked to OriginalDealer records starting with 00000 to mimimize the risk of unnecessary updates.
UPDATE Names SET ID_NUM =
(SELECT od1.ID
FROM OriginalDealer od1
INNER JOIN OriginalDealer od2
ON od1.EName = TRIM(LEADING '0' FROM od2.EName)
WHERE od2.ID = Names.ID_NUM)
WHERE EXISTS
(
SELECT 1
FROM OriginalDealer od
WHERE od.ENAME LIKE '00000%'
AND Names.ID_NUM = od.ID
);
SqlFiddle here
Note that the model of marking duplicates with a prefix like '00000' is rather fragile:
It assumes there is exactly 1 match between the 00000NAME and NAME rows in ORIGINAL_DEALER
If the above isn't true, it will attempt to set Names.ID_NUM to NULL or Fail if there is more than one match (which is probably a good thing, we don't want to corrupt data)

Oracle dynamic query

I've a simple query, vanilla select statement to which I want to filter the values provided by the user.
SELECT A,B,C,D,E FROM TAB
WHERE ....
Here the WHERE is not fixed i.e the user may input values for C, so only C should be filtered, or D or E so on. The problem is due to the user telling- filter callerID between 1 and 10 etc, but the database column has a different name. So to form a working query I have to map callerID to the columnName. As this would be in a procedure I've thought of passing the csv of userInputColumnNames, csv of dbColumns and filter begin and start. Then laboriously extract the values and match the correct db column name and form the query. This works, but however this is very cumbersome and not clean. Could there be a better way of doing this?
Do the column names in the table change?
Or are columns in the table added/removed?
If not, you can generate a number to map to each column in the table like:
SQL> SELECT column_name, ROW_NUMBER() OVER (PARTITION BY 1 ORDER BY column_name) "COLUMN_NUMBER"
2 FROM dba_tab_columns
3 WHERE table_name='DBA_USERS'
4
baim> /
COLUMN_NAME COLUMN_NUMBER
------------------------------ -------------
ACCOUNT_STATUS 1
CREATED 2
DEFAULT_TABLESPACE 3
EXPIRY_DATE 4
EXTERNAL_NAME 5
INITIAL_RSRC_CONSUMER_GROUP 6
LOCK_DATE 7
PASSWORD 8
PROFILE 9
TEMPORARY_TABLESPACE 10
USERNAME 11
USER_ID 12
12 rows selected.
Then when the user selects column 9, you know it maps to the "PROFILE" column.
If the column names can change, or if columns are added/dropped dynamically, then this won't work though.