Combining 2 different value into 1 in SQL - sql

First of all, I apologize for not being able to show my question with code. I have 2 tables. I'm merging these tables and returning a result. My values ​​include values ​​that are the same but written with different letters ( for example, INSTALL and INSTALL). These two values ​​are essentially the same. but it returns 2 different results because they are written with different letters. what I want is to convert the İNSTALL value to the INSTALL value and increase the total INSTALL value to 5. Any idea?
Column1
Values
INSTALL
2
İNSTALL
3

Use UPPER() function available in different DBMS.
select UPPER(Column1),sum(values) from Table group by UPPER(Column1)
UPPER: https://www.w3schools.com/sql/func_sqlserver_upper.asp

Depending on the anticipated overlap of letters, you could go about this a couple of ways.
Assuming the headers are the same across both tables, and only the cases are different (if they're not, use aliases in the CTE):
SELECT
LOWER(column_1) AS column_1,
SUM(Values) AS values_total
FROM (SELECT * FROM table_1 UNION SELECT * FROM table_2) combined_tables
GROUP BY 1
If there is different spelling across both tables, you could use a lower case cast of only the rightmost or leftmost letters.
SELECT
LOWER(RIGHT(column_1),3) AS column_1,
SUM(Values) AS values_total
FROM (SELECT * FROM table_1 UNION SELECT * FROM table_2) combined_tables
GROUP BY 1
If you expect a mix of misspellings, non-text characters, I'd suggest using regex to do fuzzy matching on the column values.

Related

How to ignore 00 (two leading zeros) in Select query?

I am not sure whether it is possible or not, I have one DB table which is having fields refNumber, Some of this fields values contains two leading zeros, following is example.
id.
refNumber
10001
123
10002
00456
Now I am trying to write a query which can select from this table with our without leading zeros (Only two not less or greater than two).Here is an example, for select refNumber=123 OR refNumber=00123 should return result 10001 and for refNumber=00456 OR refNumber=456 should return result of 10002. I can not use like operator because in that case other records might also be return. Is it possible through the query? if not what would be the right way to select such records? I am avoiding looping the all rows in my application.
You need to apply TRIM function on both - column and the value you want to filter by:
SELECT * FROM MyTable
WHERE TRIM(LEADING '0' FROM refNumber) = TRIM(LEADING '0' FROM '00123') -- here you put your desired ref number
Use trim()
Select * from table where trim(refnumber) IN ('123','456')
Or replace() whichever supported
Select * from table where
replace(refnumber, '0','') IN
('123','456')
While the currently accepted answer would work, be aware that at best it would cause Db2 to do a full index scan and at worst could result in a full table scan.
Not a particularly efficient way to return 1 or 2 records out of perhaps millions. This happens anytime you use an expression over a table column in the WHERE clause.
If you know there's only ever going to be 5 digits or less , a better solution would be something that does the following:
SELECT * FROM MyTable
WHERE refNumber in ('00123','123')
That assumes you can build the two possibilities outside the query.
If you really want to have the query deal with the two possibilities..
SELECT * FROM MyTable
WHERE refNumber in (LPAD(:value,5,'0'),LTRIM(:value, '0'))
If '00123' or '123' is pass in as value, the above query would find records with '00123' or '123' in refNumber.
And assuming you have an index on refNumber, do so quickly and efficiently.
If there could be an unknown number of lead zeros, then you are stuck with
SELECT * FROM MyTable
WHERE LTRIM(refNumber,'0') = LTRIM(:value, '0')
However, if you platform/version of Db2 supports indexes over an expression you'd want to create one for efficiency's sake
create index myidx
on MyTable (LTRIM('0' from refNumber))

Combining with Union Tables in SQL (values populating incorrectly)

I am trying to perform a Union on 2 tables in SQL, both with columns are MultiNational, CompanyDescrpition, GDPRojectID, Company_Code, 2019TTV, 2020TTV and 2021TTV. These two tables populate values into 2019TTV, 2020TTV and 2021TTV when I make the two separate tables, however when I perform the union, it turns into 3 columns all called TTV and then it just fills with the year number instead of the value that should be there.
Any idea why this is happening?
Here is how I am performing the union.
select multinational, companydescription, GDProjectID, company_code, 2021TTV, 2020TTV, 2019TTV FROM #TTV Union select multinational, companydescription, GDProjectID, company_code, 2021TTV, 2020TTV, 2019TTV FROM #TTVUK
If you have column names starting with numbers, you should contain them in square brackets like [2021TTV].
EDIT: To clarify, if column names start with anything besides letters, you should contain the column name in square brackets or quotes.

how to search for multiple strings in multiple columns in ORACLE SQL where clause

My situation - I have to two tables with several columns each, and I need to find certain strings in certain columns in those two tables. For example the search string could be 'ExampleString1' , 'ExampleString2%' etc around 20 strings and about 5 - 6 columns in each table.
I m using the following to find atleast one string in the multiple columns, but this even is not working.
select * from table1 a where upper('ExampleString1%') in (a.Column1, a.column2, a.column3)
Although I can do some basic sql queries, I m not that acquaint with sql. I like to know the solution or any material I can study to get to solution.
Thanks
rK
You can combine all required fields and run a check on that:
select *
from table1 a
where NVL(upper(a.Column1),'')||NVL(upper(a.column2),'')||NVL(upper(a.column3),'') like upper('ExampleString1%')
The use of upper() can be avoided here by using REGEXP_LIKE
SELECT * FROM TABLE A WHERE
REGEXP_LIKE(COLUMN1 || COLUMN2 || COLUMN3, '<search expression>', 'i')

Does MINUS QUERY validate each and Every record between the tables?

As far my knowledge , MINUS Query will not validate each and Every column data in a table. It will validate only the # of records is matching from source with # of records in target.
Let s say
Source is having
10
20
30
Target is having
10
40
30
Select Column A from Source MINUS Select Column from Target will give 0 as output. Since there is a single record mismatch will not give 1 as output. Right. Please clarify on this. I knew, but it was become a argument.
Thanks for your time.
Did you try it? It's fairly easy to test:
WITH
Source (COL) AS (
SELECT 10 FROM SYSIBM.SYSDUMMY1 UNION ALL
SELECT 20 FROM SYSIBM.SYSDUMMY1 UNION ALL
SELECT 30 FROM SYSIBM.SYSDUMMY1
)
,Target (COL) AS (
SELECT 10 FROM SYSIBM.SYSDUMMY1 UNION ALL
SELECT 40 FROM SYSIBM.SYSDUMMY1 UNION ALL
SELECT 30 FROM SYSIBM.SYSDUMMY1
)
SELECT COL FROM Source
MINUS
SELECT COL FROM Target
As you can see from the documentation:
EXCEPT or EXCEPT ALL
Derives a result table by combining two other result tables (R1 and R2). If EXCEPT ALL is specified, the result consists of all rows
that do not have a corresponding row in R2, where duplicate rows are
significant. If EXCEPT is specified without the ALL option, the result
consists of all rows that are only in R1, with duplicate rows in the
result of this operation eliminated.
For compatibility with other SQL implementations,
MINUS can be specified as a synonym for EXCEPT.
Therefore, EXCEPT (or MINUS) will only return the rows from the first table that do not have a match in the second table. In this case, you will get 20 back.
I think you are wrong. Here minus clause will return 20 as record.
For more info read this:- http://www.toadworld.com/platforms/ibmdb2/w/wiki/7696.minus-clause.aspx

distinct values from multiple fields within one table ORACLE SQL

How can I get distinct values from multiple fields within one table with just one request.
Option 1
SELECT WM_CONCAT(DISTINCT(FIELD1)) FIELD1S,WM_CONCAT(DISTINCT(FIELD2)) FIELD2S,..FIELD10S
FROM TABLE;
WM_CONCAT is LIMITED
Option 2
select DISTINCT(FIELD1) FIELDVALUE, 'FIELD1' FIELDNAME
FROM TABLE
UNION
select DISTINCT(FIELD2) FIELDVALUE, 'FIELD2' FIELDNAME
FROM TABLE
... FIELD 10
is just too slow
if you were scanning a small range in the data (not full scanning the whole table) you could use WITH to optimise your query
e.g:
WITH a AS
(SELECT field1,field2,field3..... FROM TABLE WHERE condition)
SELECT field1 FROM a
UNION
SELECT field2 FROM a
UNION
SELECT field3 FROM a
.....etc
For my problem, I had
WL1 ... WL2 ... correlation
A B 0.8
B A 0.8
A C 0.9
C A 0.9
how to eliminate the symmetry from this table?
select WL1, WL2,correlation from
table
where least(WL1,WL2)||greatest(WL1,WL2) = WL1||WL2
order by WL1
this gives
WL1 ... WL2 ... correlation
A B 0.8
A C 0.9
:)
The best option in the SQL is the UNION, though you may be able to save some performance by taking out the distinct keywords:
select FIELD1 FROM TABLE
UNION
select FIELD2 FROM TABLE
UNION provides the unique set from two tables, so distinct is redundant in this case. There simply isn't any way to write this query differently to make it perform faster. There's no magic formula that makes searching 200,000+ rows faster. It's got to search every row of the table twice and sort for uniqueness, which is exactly what UNION will do.
The only way you can make it faster is to create separate indexes on the two fields (maybe) or pare down the set of data that you're searching across.
Alternatively, if you're doing this a lot and adding new fields rarely, you could use a materialized view to store the result and only refresh it periodically.
Incidentally, your second query doesn't appear to do what you want it to. Distinct always applies to all of the columns in the select section, so your constants with the field names will cause the query to always return separate rows for the two columns.
I've come up with another method that, experimentally, seems to be a little faster. In affect, this allows us to trade one full-table scan for a Cartesian join. In most cases, I would still opt to use the union as it's much more obvious what the query is doing.
SELECT DISTINCT CASE lvl WHEN 1 THEN field1 ELSE field2 END
FROM table
CROSS JOIN (SELECT LEVEL lvl
FROM DUAL
CONNECT BY LEVEL <= 2);
It's also worthwhile to add that I tested both queries on a table without useful indexes containing 800,000 rows and it took roughly 45 seconds (returning 145,000 rows). However, most of that time was spent actually fetching the records, not running the query (the query took 3-7 seconds). If you're getting a sizable number of rows back, it may simply be the number of rows that is causing the performance issue you're seeing.
When you get distinct values from multiple columns, then it won't return a data table. If you think following data
Column A Column B
10 50
30 50
10 50
when you get the distinct it will be 2 rows from first column and 1 rows from 2nd column. It simply won't work.
And something like this?
SELECT 'FIELD1',FIELD1, 'FIELD2',FIELD2,...
FROM TABLE
GROUP BY FIELD1,FIELD2,...