Sql Query regarding Join - sql

I have two tables as follows:
Table 1:
Name | Specialisation
Table2:
Name | Slot | Date
I take user input of Name, Slot and Date. I want to display the records of Table1 for that Name such that there exists no record corresponding to the entered (Name, Slot, Date) in Table 2. What will be the SQL query for it?
Thanks in advance.

Supposing the input values were input_name, input_slot, and input_data, and the input_date was a suitable date format, one way to do it would be:
select name, specialisation from table1
where (name = input_name)
and (select name from table2
where (table2.name = input_name) and
(table2.slot = input_slot) and
(table2.date = input_date)) is NULL
Or something like that... :)

You can use a not in
select name
from table1
where name not in (
select name from table2
)
or not exists
select name
from table1
where name not exists (
select name from table2
where table2.name = table1.name
)

Related

How to fill Joining date and id based on following requirement?

I want to fill the joining date and id by creating a new view and output should be like second image
you might be looking for something like:
UPDATE mytable
SET tofill.ID = fillvalues.ID
,tofill.JOININGDATE = fillvalues.JOININGDATE
FROM mytable tofill
INNER JOIN
( SELECT DISTINCT ID, JOININGDATE, NAME
FROM mytable
WHERE ID IS NOT NULL
AND JOININGDATE IS NOT NULL
) fillvalues
ON tofill.NAME = fillvalues.NAME
WHERE tofill.ID IS NULL
OR tofill.JOININGDATE IS NULL
;
I am not familiar with Oracle, but statement should be teh same or similiar

How to validate a column of a table with combination of another columns of another table?

I have to check for the validation of a field present in one table with the fields present in another table.
I have a table with a Check_Field present in the (Main table) and this Check_Field has to be validated as a combination of two other fields present in another table(Table 2).
Main Table
Check_Field
-------------
Field_1%Field_2%
Table 2
Field_1 Field_2
----------------------
ABC XYZ
In the (Main table) I have to check for the field(Check_Field) which contains value of Field_1 from Table 2 followed by a set of predefined characters which is again followed by value of Field_2 from Table 2 and another set of predefined characters.
Something like:
SELECT * FROM MAIN_TABLE M
WHERE EXISTS (
SELECT 1
FROM TABLE2 C
WHERE M.CHECK_FIELD LIKE C.FIELD1¦¦'%'¦¦C.FIELD2¦¦'%'
)
If you have to verify the string with specific additional characters, you can remove the LIKE and insert your characters in the query.
If for example you need to check for patterns like "(field1)XX(field2)ZZ" the query will be:
SELECT * FROM MAIN_TABLE M
WHERE EXISTS (
SELECT 1
FROM TABLE2 C
WHERE M.CHECK_FIELD = C.FIELD1¦¦'XX'¦¦C.FIELD2¦¦'ZZ'
)
You can do this.
Type:
select *
from main_table
where check_field in (
select field_1 from table2
)
This would return value if present in table 2.

Compare string data between two tables

i have two tables TABLE 1 with columns
ID Text email ID
============================
1 This is Test 123#g.com
2 Make my day 1234#g.com
TABLE 2 with one column
words(column)
=============
Test
trip
day
now wat i want to do is compare the text ( each and every word) from Table 1 with each row ow word in TABLE 2, if found then the id should be logged on a different table.
example: if from TABLE1 Test is the word which is the row value in the TABLE 2 word column. so it should log ID =1 in a different table.
also once the word is found it shouldn't go for further iteration.
try this:
select *
from TABLE1
join
TABLE2
on ' '+Text+' ' like '% '+words+' %'
SQL fiddle demo
This works
SELECT t1.*,t2.words
FROM Table1 t1
JOIN Table2 t2
ON PATINDEX('%' + t2.words + '%',t1.text)>0
Output
ID Text email_ID words
1 This is Test 123#g.com Test
2 Make my day 1234#g.com day
You can to use CHARINDEX function:
select *
from TABLE1 t1
where exists
(
select 1
from TABLE2 t2
where CHARINDEX(t2.words,t1.text)>0
)
Link to documentation.

In postgresql, how can I fill in missing values within a column?

I'm trying to figure out how to fill in values that are missing from one column with the non-missing values from other rows that have the same value on a given column. For instance, in the below example, I'd want all the "1" values to be equal to Bob and all of the "2" values to be equal to John
ID # | Name
-------|-----
1 | Bob
1 | (null)
1 | (null)
2 | John
2 | (null)
2 | (null)
`
EDIT: One caveat is that I'm using postgresql 8.4 with Greenplum and so correlated subqueries are not supported.
CREATE TABLE bobjohn
( ID INTEGER NOT NULL
, zname varchar
);
INSERT INTO bobjohn(id, zname) VALUES
(1,'Bob') ,(1, NULL) ,(1, NULL)
,(2,'John') ,(2, NULL) ,(2, NULL)
;
UPDATE bobjohn dst
SET zname = src.zname
FROM bobjohn src
WHERE dst.id = src.id
AND dst.zname IS NULL
AND src.zname IS NOT NULL
;
SELECT * FROM bobjohn;
NOTE: this query will fail if more than one name exists for a given Id. (and it won't touch records for which no non-null name exists)
If you are on a postgres version >-9, you could use a CTE to fetch the source tuples (this is equivalent to a subquery, but is easier to write and read (IMHO). The CTE also tackles the duplicate values-problem (in a rather crude way):
--
-- CTE's dont work in update queries for Postgres version below 9
--
WITH uniq AS (
SELECT DISTINCT id
-- if there are more than one names for a given Id: pick the lowest
, min(zname) as zname
FROM bobjohn
WHERE zname IS NOT NULL
GROUP BY id
)
UPDATE bobjohn dst
SET zname = src.zname
FROM uniq src
WHERE dst.id = src.id
AND dst.zname IS NULL
;
SELECT * FROM bobjohn;
UPDATE tbl
SET name = x.name
FROM (
SELECT DISTINCT ON (id) id, name
FROM tbl
WHERE name IS NOT NULL
ORDER BY id, name
) x
WHERE x.id = tbl.id
AND tbl.name IS NULL;
DISTINCT ON does the job alone. Not need for additional aggregation.
In case of multiple values for name, the alphabetically first one (according to the current locale) is picked - that's what the ORDER BY id, name is for. If name is unambiguous you can omit that line.
Also, if there is at least one non-null value per id, you can omit WHERE name IS NOT NULL.
If you know for a fact that there are no conflicting values (multiple rows with the same ID but different, non-null names) then something like this will update the table appropriately:
UPDATE some_table AS t1
SET name = (
SELECT name
FROM some_table AS t2
WHERE t1.id = t2.id
AND name IS NOT NULL
LIMIT 1
)
WHERE name IS NULL;
If you only want to query the table and have this information filled in on the fly, you can use a similar query:
SELECT
t1.id,
(
SELECT name
FROM some_table AS t2
WHERE t1.id = t2.id
AND name IS NOT NULL
LIMIT 1
) AS name
FROM some_table AS t1;

SQL how to find rows which have highest value of specific column

For example, the table has columns MYINDEX and NAME.
MYINDEX | NAME
=================
1 | BOB
2 | BOB
3 | CHARLES
Ho do I find row with highest MYINDEX for specific NAME? E.g. I want to find ROW-2 for name "BOB".
SELECT Max(MYINDEX) FROM table WHERE NAME = [insertNameHere]
EDIT: to get the whole row:
Select * //never do this really
From Table
Where MYINDEX = (Select Max(MYINDEX) From Table Where Name = [InsertNameHere]
There are several ways to tackle this one. I'm assuming that there may be other columns that you want from the row, otherwise as others have said, simply name, MAX(my_index) ... GROUP BY name will work. Here are a couple of examples:
SELECT
MT.name,
MT.my_index
FROM
(
SELECT
name,
MAX(my_index) AS max_my_index
FROM
My_Table
GROUP BY
name
) SQ
INNER JOIN My_Table MT ON
MT.name = SQ.name AND
MT.my_index = SQ.max_my_index
Another possible solution:
SELECT
MT1.name,
MT1.my_index
FROM
My_Table MT1
WHERE
NOT EXISTS
(
SELECT *
FROM
My_Table MT2
WHERE
MT2.name = MT1.name AND
MT2.my_index > MT1.my_index
)
SELECT MAX(MYINDEX) FROM table
WHERE NAME = 'BOB'
For the whole row, do:
SELECT * FROM table
WHERE NAME = 'BOB'
AND MyIndex = (SELECT Max(MYINDEX) from table WHERE NAME = 'BOB')
If you wanted to see the highest index for name = 'Bob', use:
SELECT MAX(MYINDEX) AS [MaxIndex]
FROM myTable
WHERE Name = 'Bob'
If you want to skip the inner join, you could do:
SELECT * FROM table WHERE NAME = 'BOB' ORDER BY MYINDEX DESC LIMIT 1;
Use
FROM TABLE SELECT MAX(MYINDEX), NAME GROUP BY NAME