SQL Select multiple rows using where in one table - sql

I have a table named "Student".
Student
id | name | age
1 | john | 10
2 | jack | 10
3 | jerry| 10
I wanna select 1 and 2 rows. I wrote that Select * from Student where name=john and name=jack
But return "Empty Set".
How do i do it. Help me.

select *
from student
where name in ('john', 'jack')
Or
select *
from student
where name = 'john'
or name = 'jack'

You need an OR rather than an AND.
Whatever conditions your write, it checks them all against each record. As no single record has both name = 'john' AND name = 'jack' they all fail.
If, instead, you use OR...
- The 1st record yields TRUE OR FALSE which is TRUE.
- The 2nd record yields FALSE OR TRUE which is TRUE.
- The 3rd record yields FALSE OR FALSE which is FALSE.
Select * from Student where name='john' OR name='jack'
Or, using a differnt way of saying it all...
SELECT * FROM Student WHERE name IN ('john', 'jack')

Use single quotes to surround your values, plus use and instead of or:
where name='john' or name = 'jack'

try this one.
declare #names varchar(100)
set #names='john,jack'
Select * from Student
where charIndex(',' + rtrim(cast(name as nvarchar(max))) + ',',',' +isnull(#names,name) +',') >0

Related

Opposite of SUBSTR for big query

I have two tables in bigquery that can be matched on a ID. Unfortunately one of the ids has a prefix (3 digits that is not consistent)
For example, one ID is "12345" (Table two / id) and the second ID is "T1_12345" (Table one / Link_id)
When selecting from the first table I can just use SUBSTR to remove the prefix before working in the second table. However, if I want to first select in the second table with the shorter prefix and than in the first table I can't find a way to do that.
The code below is an example of what i'm working with.
I'm looking for something similar to the RIGHT or SUBSTR functions, but in reverse basically.
SELECT body from [table] where link_id in
(SELECT
id
FROM
[table_two]
WHERE
author == "Username")
This code isn't correct, but might give a clearer picture of what i'm trying to do.
SELECT body from [table] where "12345" in
(SELECT
"T1_12345"
FROM
[table_two]
WHERE
author == "Username")
Edit:
For example, if I had these two tables...
Table 1
| First_name| Link ID |
|-----------|-----------|
| James |T1_12345 |
| John |T2_12346 |
Table 2
| Surname| ID |
|-----------|--------|
| Tobbin |12345 |
| Peterson |12346 |
And I ran this query...
SELECT first_name from [table 1] where Link_ID in
(SELECT
ID
FROM
[table_two]
WHERE
Surname == "Peterson")
The output I want is: John Peterson
Below is for BigQuery Standard SQL
#standardSQL
SELECT first_name
FROM `project.dataset.table_one`
WHERE SUBSTR(Link_ID, 4) IN (
SELECT ID
FROM `project.dataset.table_two`
WHERE Surname = 'Peterson'
)
with result:
Row first_name
1 John
--
#standardSQL
SELECT CONCAT(first_name, ' ', Surname) full_name
FROM `project.dataset.table_one`
LEFT JOIN `project.dataset.table_two`
ON SUBSTR(Link_ID, 4) = ID
WHERE Surname = 'Peterson'
with result:
Row full_name
1 John Peterson
Below is for BigQuery Legacy SQL
#legacySQL
SELECT first_name
FROM (
SELECT First_name, SUBSTR(Link_ID, 4) short_ID
FROM [project:dataset.table_one]
)
WHERE short_ID IN (
SELECT ID
FROM [project:dataset.table_two]
WHERE Surname = 'Peterson'
)
--
#legacySQL
SELECT CONCAT(first_name, ' ', Surname) full_name
FROM (
SELECT First_name, SUBSTR(Link_ID, 4) short_ID
FROM [project:dataset.table_one]) t1
LEFT JOIN [project:dataset.table_two] t2
ON short_ID = ID
WHERE Surname = 'Peterson'
If you want to use in, can't you just use this?
SELECT body
FROM [table]
WHERE link_id IN (SELECT SUBSTR(id, 4)
FROM [table_two]
WHERE author = 'Username'
);

Am I on the right track..finding matches between two tables(SQL)

I'm a SQL noob and I'm wondering if someone could give me
some help with the folowing problem:
So I have two tables "Schools" and "Teachers".
the "search_key" column of the "Schools" table is one big string that
combines teachers name and other elements (example: "ENGLISH | JANE | [90, 56])
So what I'm trying to do is match the string from the column "name"
of the "teachers" table with that previous one, getting the cells that have a match.
SELECT * FROM(
SELECT substr(a.search_key, 6, instr(a.search_key, '|'))
FROM schools a
) JOIN teachers s ON a.search_key = s.search_key
This is what Ive been trying to do, substring and try and match, but no luck so far.
Any ideas?
I'm not sure why it would be more complicated than:
SELECT *
FROM schools s
INNER JOIN teachers t ON t.teacher_name LIKE '%' + s.search_key + '%'
This should get you going -
WITH SCHOOLS AS (
SELECT
'ENGLISH | JANE | [90,56]' AS SEARCH_KEY
FROM
DUAL
),TEACHER AS (
SELECT
'JANE' AS NAME
FROM
DUAL
) SELECT
S.SEARCH_KEY
FROM
SCHOOLS S,
TEACHER T
WHERE
S.SEARCH_KEY LIKE '%' || T.NAME || '%';
Output -
SEARCH_KEY
ENGLISH | JANE | [90, 56]
Another approach would be -
WITH SCHOOLS AS (
SELECT
'ENGLISH | JANE | [90,56]' AS SEARCH_KEY
FROM
DUAL
),TEACHER AS (
SELECT
'JANE' AS NAME
FROM
DUAL
) SELECT
S.SEARCH_KEY
FROM
SCHOOLS S,
TEACHER T
WHERE
TRIM(REGEXP_SUBSTR(S.SEARCH_KEY,'(\S*)(\W)',1,3)) = T.NAME;
This works if the name is always the 2nd field value in the SEARCH_KEY field de-limited by |

How to create an Oracle SQL statement in the following case?

I have an oracle table with three clumns and three data records as shown below
ID FIRST_NAME LAST_NAME
01 Jason Martin
02 Alison Mathews
03 Robert Black
I want to select the first name by a given ID.
If the ID exists, i.e., it is a value among 01, 02, and 03, the corresponding FIRST_NAME needs to be displayed;
If the ID does not exist, a * symbol needs to be displayed.
Could you help me creating such an oracle SQL statement?
Many thanks in advance.
Do an outer join, this example using id = 2:
select coalesce(FIRST_NAME, '*')
from dual
left join tablename on id = 2
Use a CASE statement:
SELECT ID,
CASE WHEN ID IN ('01', '02', '03') THEN FIRST_NAME ELSE '*' END
FROM yourTable
Note: I assumed, based on your input data, that the ID column is VARCHAR and not numeric because of the leading zeroes. If ID is numeric, then change the query to this:
SELECT ID,
CASE WHEN ID IN (1, 2, 3) THEN FIRST_NAME ELSE '*' END
FROM yourTable

Retrieve one row in select statement which generates multiple rows (by avoiding NULL rows if possible)

I want to get the Name from this table but I only have the Number which is not unique. How do I get the correct Name (please give me some SQL syntax)?
Below the database table you can see the input and expected output for
Database Table
Number Name
1 Anna
1 Anna
2 Brad
2 NULL
2 NULL
2 NULL
3 NULL
3 NULL
4 Adam
5 NULL
Input and expected output:
Number (Input) Name (Expected outpu)
1 Anna
2 Brad
3 NULL
4 Adam
5 NULL
What do I need to add to my query to make it work?
SELECT Name FROM tablename
WHERE Number='chosen number'
A simple MAX/GROUP BY will return your expected result set:
SELECT Number, MAX(Name)
FROM table name
GROUP BY 1;
Btw, NUMBER is a Reserved Name in Teradata
SELECT
number,
MAX(name)
FROM
your_table
GROUP BY
number
And/Or
SELECT
MAX(name)
FROM
your_table
WHERE
number = x
MAX, MIN, etc, all treat NULL as the last value; you only get a NULL if all values are NULL.
This is a step in the right direction, the problem is that you will still get NULL aswell if you have a row with NULL give me a bit to figure out how to filter those out if there is a name
Mysql would be this:
http://sqlfiddle.com/#!9/4beca/1
SELECT DISTINCT Name
FROM mytable
WHERE Number=1 AND Name is not null
UNION
SELECT NULL
FROM mytable
LIMIT 1
SQL-Server would be this:
http://sqlfiddle.com/#!3/f4078/11
SELECT TOP 1 sub.Name
FROM
(SELECT DISTINCT Name
FROM mytable
WHERE Number=1 AND Name is not null
UNION
SELECT NULL AS Name
FROM mytable) AS sub

UPDATE and return some rows twice

I try to update and return rows. The problem is I use a nested select with UNION to get some rows twice and I want to get them returned twice. Example:
Table:
First_name | last_name | ready
-----------+-----------+------
john | doe | false
| smith | false
jane | | false
Query:
With list(name) as (
Select First_name
from table1
where First_name Not null and ready=false
union
Select last_name
from table1
where last_name Not null and ready=false
)
Select * from list
This returns:
John
jane
doe
smith
Now I want to update the rows found by the select and use update ... returning instead. But the update only returns the three affected rows, while I want it to return the rows as the select in the example does. Is there any way?
Rewrite to:
WITH cte AS (
UPDATE table1
SET ready = true
WHERE (first_name IS NOT NULL OR last_name IS NOT NULL)
AND NOT ready
RETURNING first_name, last_name
)
SELECT first_name FROM cte WHERE first_name IS NOT NULL
UNION ALL
SELECT last_name FROM cte WHERE last_name IS NOT NULL;
Same result, just shorter and faster: This query accesses table1 a single time instead of three times like in your original.
(Verify the superior performance with EXPLAIN ANALYZE on a test table.)
UNION ALL like #Clodoaldo already mentioned. UNION would eliminate duplicates, which is substantially slower (and probably wrong here).
with list(name) as (
select first_name
from table1
where first_name is not null and ready=false
union all
select last_name
from table1
where last_name is not null and ready=false
), u as (
update table1
set ready = true
where
(first_name is not null or last_name is not null)
and
not ready
)
select * from list
You need union all to have the four rows. It is is [not] null