Compare varchar values postgresql - sql

I'm new in the db world and I'm trying to do my first queries.
I have two tables and I need compare the value of the columnA, in the first table, with the value of the columnB in the second table.
I would like to know what values in the columnA are in the columnB. Both columns are varchar type.
I've tried this two queries:
select *
from tableA
join tableB
on (tableA.columnA = tableB.columnB);
select *
from tableA
where columnA in (select columnB
from tableB);
But both get me back empty table.
I checked the values manually, and there are many equal values.
Maybe the = isn't the right operator with the string values?
This is a simple example of what I would do, with the expected result at the end.
TableA
columnA descriptionA
EF8236PA xyx
EF7843DV dgfd
EF6535MD dshr
EF3274LK hghg
EF6940BN fdtsg
EF3405TJ dsbfbs
TableB
columnB
EF3405TJ
EF6940BN
EF6535MD
Result:
EF3405TJ
EF6940BN
EF6535MD

Both of your queries are looking fine. you can add few more conditions in the where clause that will make it work.
Example:
select *
from tableA
join tableB
on (upper(trim(tableA.columnA)) = upper(trim(tableB.columnB)));
Trim will cut down extra spaces and upper will make the search case insensitive.
Hope this will help.

I would like to know what values in the columnA are in the columnB.
Strictly speaking, this query is a correct (and fast) query to implement what you ask:
SELECT DISTINCT columnA
FROM tableA a
WHERE EXISTS (SELECT 1 FROM tableB WHERE columnB = a.columnA);
The manual about EXISTS.
But neither of your queries should return empty sets. There may be whitespace or other invisible characters fooling you. Test with:
SELECT * FROM tableA WHERE columnA = 'EF6940BN';
SELECT * FROM tableB WHERE columnB = 'EF6940BN';

I tried all your suggestions, but no one works.
So I tried run the code on another postgre and the same code that I wrote above works.
I don't understand why, the postgre's versions are the same

Related

Display value from column B if column A is NULL

I am wondering how i can display data from column B if Column A is null. The reason is if we get a product from one of our manufactures it is put in a different column. However, when i go to build the report the two columns essentially the same thing and it is throwing the graph way off. Any help would be appreciated.
Something like this maybe?
Case When column A isnull then column B?
Use ISNULL() or COALESCE(), or CASE
SELECT ISNULL(ColumnA, ColumnB) AS [YourColumn]
FROM FOO
OR
SELECT COALESCE(ColumnA, ColumnB) AS [YourColumn]
FROM FOO
OR
SELECT CASE WHEN ColumnA IS NULL THEN
ColumnB
ELSE
ColumnA
END AS [YourColumn]
FROM FOO

Minus operator in sql

I am trying to create a sql query with minus.
I have query1 which returns 28 rows with 2 columns
I have query2 which returns 22 row2 with same 2 columns in query 2.
when I create a query query1 minus query 2 it should have only show the 28-22=6 rows.
But it showing up all the 28 rows returned by query1.
Please advise.
Try using EXCEPT instead of MINUS. For Example:
Lets consider a case where you want to find out what tasks are in a table that haven't been assigned to you(So basically you are trying to find what tasks could be available to do).
SELECT TaskID, TaskType
FROM Tasks
EXCEPT
SELECT TaskID, TaskType
FROM Tasks
WHERE Username = 'Vidya'
That would return all the tasks that haven't been assigned to you. Hope that helps.
If MINUS won't work for you, the general form you want is the main query in the outer select and a variation of the other query in a not exists clause.
select <insert list of fields here>
from mytable a
join myothertable b
on b.aId = a.aid
where not exists (select * from tablec c where a.aid = c.aid)
The fields might not be exactly alike. may be one of the fields is char(10) and the other is char(20) and they both have the string "TEST" in them. They might "look" the same.
If the database you are working on supports "INTERSECT", try this query and see how many are perfectly matching results.
select field1, field2 from table1
intersect
select field1, field2 from table2
To get the results you are expecting, this query should give you 22 rows.
something like this:
select field1, field2, . field_n
from tables
MINUS
select field1, field2, . field_n
from tables;
MINUS works on the same principle as it does in the set operations. Suppose if you have set A and B,
A = {1,2,3,4}; B = {3,5,6}
then, A-B = {1,2,4}
If A = {1,3,5} and B = {2,4,6}
then, A-B = {1,3,5}. Here the count(A) before and after the MINUS operation will be the same, as it does not contain any overlapping terms with set B.
On similar lines, may be the result set obtained in query 2 may not have matching terms with the result of query1. Hence you are still getting 28 instead of 6 rows.
Hope this helps.
It returns the difference records in the upper query which are not contained by the second query.
In your case for example
A={1,2,3,4,5...28} AND B={29,30} then A-B={1,2,3....28}

Deleting at most one record for each unique tuple combination

I want to delete at most one record for each unique (columnA, columnB)-tuple in my following delete statement:
DELETE FROM tableA
WHERE columnA IN
(
--some subqueryA
)
AND columnB IN
(
--some subqueryB
)
How is this accomplished? Please only consider those statements that work when used against MSS 2000 (i.e., T-SQL 2000 syntax). I can do it with iterating through a temptable but I want to write it using only sets.
Example:
subqueryA returns 1
subqueryB returns 2,3
If the original table contained
(columnA, columnB, columnC)
5,2,5
1,2,34
1,2,45
1,3,86
Then
1,2,34
1,3,86
should be deleted. Each unique (columnA, columnB)-tuple will appear at most twice in tableA and each time I run my SQL statement I want to delete at most one of these unique combinations - never two.
If there is one record for a given unique (columnA, columnB)-tuple,
delete it.
If there are two records for a given unique (columnA,
columnB)-tuple, delete only one of them.
Delete tabA
from TableA tabA
Where tabA.columnC in (
select max(tabAA.columnC) from TableA tabAA
where tabAA.columnA in (1)
and tabAA.columnB in (2,3)
group by tabAA.columnA,tabAA.columnB
)
How often are you going to be running this that it matters whether you use temp tables or not? Maybe you should consider adding constraints to the table so you only have to do this once...
That said, in all honesty, the best way to do this for SQL Server 2000 is probably to use the #temp table as you're already doing. If you were trying to delete all but one of each dupe, then you could do something like:
insert the distinct rows into a separate table
delete all the rows from the old table
move the distinct rows back into the original table
I've also done things like copy the distinct rows into a new table, drop the old table, and rename the new table.
But this doesn't sound like the goal. Can you show the code you're currently using with the #temp table? I'm trying to envision how you're identifying the rows to keep, and maybe seeing your existing code will trigger something.
EDIT - now with better understood requirements, I can propose the following query. Please test it on a copy of the table first!
DELETE a
FROM dbo.TableA AS a
INNER JOIN
(
SELECT columnA, columnB, columnC = MIN(columnC)
FROM dbo.TableA
WHERE columnA IN
(
-- some subqueryA
SELECT 1
)
AND columnB IN
(
-- some subqueryB
SELECT 2 UNION SELECT 3
)
GROUP BY columnA, columnB
) AS x
ON a.columnA = x.columnA
AND a.columnB = x.columnB
AND a.columnC = x.columnC;
Note that this doesn't confirm that there are exactly one or two rows that match the grouping on columnA and columnB. Also note that if you run this twice it will delete the remaining row that still matches the subquery!

Matching two columns in MySQL

I'm quite new to SQL and have a question about matching names from two columns located within a table:
Let's say I want to use the soundex() function to match two columsn. If I use this query:
SELECT * FROM tablename WHERE SOUNDEX(column1)=SOUNDEX(column2);
a row is returned if the two names within that row match. Now I'd also like to get those name matches between column1 and column2 that aren't in the same row. Is there a way to automate a procedure whereby every name from column1 is compared to every name from column2?
Thanks :)
p.s.: If anyone could point me in the direction of a n-gram/bi-gram matching algorithm that is easy for a noob to implement into mysql that would be good as well.
If your table has a key, say id, you can try:
select A.column1, B.column2
from tablename as A, tablename as B
where (A.id != B.id) and (SOUNDEX(A.column1) = SOUNDEX(B.column2))
You can join the table to itself on that relationship as such:
SELECT * FROM tablename t1 JOIN tablename t2
ON SOUNDEX(t1.column1) = SOUNDEX(t2.column2);

how to select a row where one of several columns equals a certain value?

Say I have a table that includes column A, column B and column C. How do I write I query that selects all rows where either column A OR column B OR column C equals a certain value? Thanks.
Update: I think forgot to mention my confusion. Say there is another column (column 1) and I need to select based on the following logic:
...where Column1 = '..' AND (ColumnA='..' OR ColumnB='..' OR ColumnC='..')
Is it valid to group statements as I did above with parenthesis to get the desired logic?
Unless I'm missing something here...
SELECT * FROM MYTABLE WHERE COLUMNA=MyValue OR COLUMNB=MyValue OR COLUMNC=MyValue
I prefer this way as its neater
select *
from mytable
where
myvalue in (ColumnA, ColumnB, ColumnC)
SELECT *
FROM myTable
WHERE (Column1 = MyOtherValue) AND
((ColumnA = MyValue) OR (ColumnB = MyValue) OR (ColumnC = MyValue))
Yes, it's valid to use parentheses. However, if you're searching multiple columns for the same value, you may want to consider normalizing the database.