SQL - Find specific value in a specific table - sql

Say I have a table called "Team" with the following columns:
ID, MemberName ,ManagerName,Title
And I would like to retrieve all rows where a value "John" exists.
Assume "John" exists in a row for the MemberName column, and that "John" would exist in another row under the "ManagerName" column.
Please assume would have large number of columns. Greater than 50, and do would not know where the value would fall under statically.

If you need an exact match for "John" you can use following query:
Select *
From Team
Where MemberName = 'John' or ManagerName = 'John'
If you need all rows where "John" could be a part of the string then you can use like:
Select *
From Team
Where MemberName like '%John%' or ManagerName like '%John%'

Generally, you need to specify all the columns your are searching from in SQL.
SELECT * FROM Team WHERE 'John' IN (col1, col2, col3, ..., colN) ;
However that depends.
If you are using MySQL you can Search Table Data. From the MySQL Workbench right click the table , and choose Search Table Data.
If you are using PostgreSQL take a look at the following:
https://stackoverflow.com/a/52715388/10436747

Related

How to execute a select with a WHERE using a not-always-existing column

Simple example: I have some (nearly) identical tables with personal data (age, name, weight, ...)
Now I have a simple, but long SELECT to find missing data:
Select ID
from personal_data_a
where
born is null
or age < 1
or weight > 500
or (name is 'John' and surname is 'Doe')
Now the problem is:
I have some personal_data tables where the column "surname" does not exit, but I want to use the same SQL-statement for all of them. So I have to check (inside the WHERE clause) that the last OR-condition is only used "IF the column surname exists".
Can it be done in a simple way?
You should have all people in the same table.
If you can't do that for some reason, consider creating a view. Something like this:
CREATE OR REPLACE VIEW v_personal_data
AS
SELECT id,
born,
name,
surname,
age,
weight
FROM personal_data_a
UNION ALL
SELECT id,
born,
name,
NULL AS surname, --> this table doesn't contain surname
age,
weight
FROM personal_data_b;
and then
SELECT id
FROM v_personal_data
WHERE born IS NULL
OR age < 1
OR ( name = 'John'
AND ( surname = 'Doe'
OR surname IS NULL))
Can it be done in a simple way?
No, SQL statements work with static columns and the statements will raise an exception if you try to refer to a column that does not exist.
You will either:
need to have a different query for tables with the surname column and those without;
have to check in the data dictionary whether the table has the column or not and then use dynamic SQL to build your query; or
to build a VIEW of the tables which do not have that column and add the column to the view (or add a GENERATED surname column with a NULL value to the tables that are missing it) and use that instead.
While dynamic predicates are usually best handled by the application or by custom PL/SQL objects that use dynamic SQL, you can solve this problem with a single SQL statement using DBMS_XMLGEN, XMLTABLE, and the data dictionary. The following code is not what I would call "simple", but it is simple in the sense that it does not require any schema changes.
--Get the ID column from a PERSONAL table.
--
--#4: Get the IDs from the XMLType.
select id
from
(
--#3: Convert the XML to an XMLType.
select xmltype(personal_xml) personal_xmltype
from
(
--#2: Convert the SQL to XML.
select dbms_xmlgen.getxml(v_sql) personal_xml
from
(
--#1: Use data dictionary to create SQL statement that may or may not include
-- the surname predicate.
select max(replace(replace(
q'[
Select ID
from #TABLE_NAME#
where
born is null
or age < 1
or weight > 500
or (name = 'John' #OPTIONAL_SURNAME_PREDICATE#)
]'
, '#TABLE_NAME#', table_name)
, '#OPTIONAL_SURNAME_PREDICATE#', case when column_name = 'SURNAME' then
'and surname = ''Doe''' else null end)) v_sql
from all_tab_columns
--Change this literal to the desired table.
where table_name = 'PERSONAL_DATA_A'
)
)
where personal_xml is not null
)
cross join xmltable
(
'/ROWSET/ROW'
passing personal_xmltype
columns
id number path 'ID'
);
See this db<>fiddle for a runnable example.

selecting with a column being one of two possible values

I have a table called "people" with a column named "name". I would like to select all rows where the name is "bob" or "john". I have tried the following and many variants of it, none of which work. How can I do this correctly?
select * from people where name is bob or john;
Thanks
To compare a column with a value you need to use = not IS
select *
from people
where name = 'bob'
or name = 'john';
Alternatively you can use the IN operator.
select *
from people
where name IN ('bob','john');
Note that string comparison is case-sensitive in SQL. So the above will not return rows where the name is Bob or John

I want to merge the duplicate names in my table or at least see the names that are unique and look alike

I have a employee table with schema as follows:
Id Name Birthday DeathDay Startdate EndDate
The problem is that I have data as follows:
Bergh Celestin 06/09/1791 14/12/1861
Bergh Célestin 06/09/1791 14/12/1861
Bergh Francois 04/04/1958 11/12/2001
Bergh Jozef Francois 04/04/1958 11/12/2001
Now i want to merge these records as 1 as they are the same person how can i do that?
Also, if I just want to display the list of only those person from the table whose names are possibly same, like above, how can I do that?
I used:
select Distinct name,birthday,deathday from table
but that is not good enough.
I would use a function (.NET or SQL) of sorts to remove the accents as per https://stackoverflow.com/a/12715102/1662973 and then group on that together with the dates. You will need to group on something, as essentially "Bergh Célestin" could actually be a different person to "Bergh Celestin".
Sample:
select
RemoveExtraChars(name)
,birthday
,deathday
from
TABLE
group by
RemoveExtraChars(name)
,birthday
,deathday
For your second Question you can use SQL LIKE Operator:
SELECT column_name(s)
FROM table_name
WHERE column_name LIKE pattern;

how to transform vertical fields in a table to horizontal result by SQL

I have a table like this:
create table t1 {
person_id int,
item_name varchar(30),
item_value varchar(100)
};
Suppose person_id+item_name is the composite key, now I have some data (5 records) in table t1 as below:
person_id ====item_name ====== item_value
1 'NAME' 'john'
1 'GENDER' 'M'
1 'DOB' '1970/02/01'
1 'M_PHONE' '1234567890'
1 'ADDRESS' 'Some Addresses unknown'
Now I want to use SQL (or combing store procedure/function or whatever) to query the above result (1 result set) become:
NAME==GENDER==DOB========M_PHONE=======ADDRESS===============
1 M 1970/02/01 1234567890 Some Addresses unknown
How should I do ?
Thank you for your help.
Regardless of the database you are using, the concept of what you are trying to achieve is called "Pivot Table".
Here's an example for mysql:
http://en.wikibooks.org/wiki/MySQL/Pivot_table
Some databases have builtin features for that, see the links below.
SQLServer:
http://msdn.microsoft.com/de-de/library/ms177410.aspx
Oracle:
http://www.dba-oracle.com/t_pivot_examples.htm
You can always create a pivot by hand. Just select all the aggregations in a result set and then select from that result set. Note, in your case, you can put all the names into one column using concat (i think that's group_concat in mysql), since you cannot know how many names are related to a person_id.
Finally, I found the solution in PostgreSQL:
select * from crosstab ('select person_id, item_name, item_value from t1 where person_id = 1 ')
as virtual_table ( person_id integer, name varchar, gender varchar, dob varchar, m_phone varchar, address varchar)
Also need to install the crosstab function on Postgres. See more: http://www.postgresql.org/docs/8.3/static/tablefunc.html

MySQL SELECT query string matching

Normally, when querying a database with SELECT, its common to want to find the records that match a given search string.
For example:
SELECT * FROM customers WHERE name LIKE '%Bob Smith%';
That query should give me all records where 'Bob Smith' appears anywhere in the name field.
What I'd like to do is the opposite.
Instead of finding all the records that have 'Bob Smith' in the name field, I want to find all the records where the name field is in 'Robert Bob Smith III, PhD.', a string argument to the query.
Just turn the LIKE around
SELECT * FROM customers
WHERE 'Robert Bob Smith III, PhD.' LIKE CONCAT('%',name,'%')
You can use regular expressions like this:
SELECT * FROM pet WHERE name REGEXP 'Bob|Smith';
Incorrect:
SELECT * FROM customers WHERE name LIKE '%Bob Smith%';
Instead:
select count(*)
from rearp.customers c
where c.name LIKE '%Bob smith.8%';
select count will just query (totals)
C will link the db.table to the names row you need this to index
LIKE should be obvs
8 will call all references in DB 8 or less (not really needed but i like neatness)