Select values from one table depending on referenced value in another table - sql

I have two tables in my SQLite Database (dummy names):
Table 1: FileID F_Property1 F_Property2 ...
Table 2: PointID ForeignKey(fileid) P_Property1 P_Property2 ...
The entries in Table2 all have a foreign key column that references an entry in Table1.
I now would like to select entries from Table2 where for example F_Property1 of the referenced file in Table1 has a specific value.
I tried something naive:
select * from Table2 where fileid=(select FileID from Table1 where F_Property1 > 1)
Now this actually works..kind of. It selects a correct file id from Table1 and returns entries from Table2 with this ID. But it only uses the first returned ID. What I need it to do is basically connect the returned IDs from the inner select by OR so it returns data for all the IDs.
How can I do this? I think it is some kind of cross-table-query like what is asked here What is the proper syntax for a cross-table SQL query? but these answers contain no explaination of what they are actually doing so I'm struggeling with any implementation.
They are using JOIN statements, but wouldn't this mix entries from Table1 and Table2 together while only checking matching IDs in both tables? At least that is how I understand this http://www.codeproject.com/Articles/33052/Visual-Representation-of-SQL-Joins
As you may have noticed from the style, I'm very new to using databases in general, so please forgive me if not everything is clear about what I want. Please leave a comment and I will try to improve the question if neccessary.

The = operator compares a single value against another, so it is assumed that the subquery returns only a single row.
To check whether a (column) value is in a set of values, use IN:
SELECT *
FROM Table2
WHERE fileid IN (SELECT FileID
FROM Table1
WHERE F_Property1 > 1)

The way joins work is not by "mixing" the data, but sort of combining them based on the key.
In your case (I am assuming the key field in Table 1 is unique), if you join those two tables on the primary key field, you will end up with all the entries in table2 plus all corresponding fields from table1. If you were doing this:
select * from table1, table2 where table1.fieldID=table2.foreignkey;
then, providing your key fields are set up right, you will end up with the following:
PointID ForeignKey(fileid) P_Property1 P_Property2 FileID F_Property1 F_Property2
The field values from table1 would be from matching rows.
Now, if you do this:
select table1.* from table 1, table2 where
table1.fieldID=table2.foreignkey and F_Property1>1;
Would essentially get the same set of records, but will only show the columns from the second table, and only those that satisfy the where condition for the first one.
Hope this helps :)

If I understood your question correctly this will get the job done.
Select t2.*
from table1 t1
inner join table2 t2 on t2.id = t1.id
where t1.Prop = 'SomeValue'

Related

How do I copy rows from one table to another in SQL?

I have been trying to copy the data listed in one table to another that are both located in the same database. However, every time I have everything entered, it runs the query and says 0 rows updated.
I have tried several variations in an attempt to get this to work. One such attempt is as listed below. I found this while researching in an attempt to get this done.
UPDATE
t1
SET
t1.column = t2.column
FROM
Table1 t1
INNER JOIN Table2 t2
ON t1.id = t2.id;
Any help on this would be greatly appreciated.
UPDATE will only modify records that already exist, if you want to insert rows that exist on another table use INSERT.
You can combine INSERT and SELECT to copy a whole table1 into a table2.
INSERT INTO table2 SELECT * FROM table1;
You can use INSERT IGNORE to copy only records that don't exist yet (based on unique keys).
You can also specify fields to copy in case the tables are different:
INSERT INTO table2 (id, first_name, last_name) SELECT id, name, surname FROM table1;

SQL: Add multiple rows from one table to another when no data for that date in new table

I'm trying to update medical data from one table to another after switching from one system to another. We have two tables, for simplicity I'll make this a simple example. There are many columns in these tables in reality (not just 5).
Table1:
name, date, var1, var2, var3
Table2:
name, date, var1a, var2a, var3a
I want to transfer data from Table 1 to Table 2 for any rows where there isn't previous data for that date, where var1 = var1a, etc (same columns with different names).
I was trying to do something with a loop, but realized that may not be necessary.
I had gotten this far but keep wasn't sure if this was ok:
UPDATE Table2 VALUES (date, var1a, var2a, var3a)
SELECT date, var1, var2, var3 FROM Table1
Is that correct syntax so far? Or do I need to map the variables to translate var1 into var1a, etc?
How do I add a check to make sure I don't overwrite any data already in Table1? I don't want to add data if there is already data for that date/name combination.
Thanks!
You can INSERT into TABLE2 all values from TABLE1 that do not already exist in Table2:
INSERT INTO Table2 (date, var1a, var2a, var3a)
SELECT date, var1, var2, var3
FROM Table1 t1
WHERE NOT EXISTS (SELECT 1 FROM Table2 t2 WHERE t2.date = t1.date)
Already existing values are specified by comparing the date column. You can add any other predicates in the SELECT subquery of the NOT EXISTS expression to suit your needs.
You could use an update with a join. And you dont need to update the date column since that's what you are using to find the matches in the 2 tables.
Either you generate a dynamic query based on the empty/null valued columns, or you could do something like the below, which puts the same value in the column if it exists in table2 or else puts the corresponding value from table1.
The below approach requires less logic and easier to implement but will produce IO equivalent to updating the entire table.
update tbl2
set val1a=isnull(val1a,val1)
, val2a=isnull(val2a,val2)
, val3a=isnull(val3a.val3)
from table1 tbl1
inner join table2 tbl2
on tbl1.name=tbl2.name
and tbl1.date=tbl2.date
Considerations:
The approach requires less logic and easier to implement but will produce IOs equivalent to updating the entire table2. If you have a smallish table i would go with this approach.
If its a big table then you should look into building specific query sets to reduce IO
This code is tested in Access but something very similar should work in SQL Server 2012:
UPDATE Table2 RIGHT JOIN Table1 ON Table2.date = Table1.date
SET Table2.name = Table1.name, Table2.date = Table1.date, Table2.var1 = Table1.var1a, Table2.var2 = Table1.var2a, Table2.var3 = Table1.var3a
WHERE (Table2.date Is Null);
Explanation: this uses a right join so that within the query all the data from Table1 is present and where there is a matched date for Table2 that data is present too. We then ignore all cases where there is any data for Table2 and update the query in all other cases - the update in fact inserts new data into Table2.

Oracle Compare data between two different table

I have two table one is having all field VARCHAR2 but other having different type for different data.
For Example :
Table One
==========================
Col 1 VARCHAR2 UNIQUE KEY
Col 2 VARCHAR2
Col 3 VARCHAR2
===========================
Table Two
==========================
Col One VARCHAR2 UNIQUE KEY
Col Two TIMESTAMP
Col Three NUMBER
==========================
we are having one mapping table. it denotes which column of Table One has to compare with which column of Table Two.
For Example
Mapping Table
==============================
Table One Table Two
==============================
Col 1 Col One
Col 2 Col Three
Col 3 Col Two
==============================
Now with the help of UNIQUE KEY of TABLE ONE we have to find same row in TABLE TWO and compare rows column by column and get changes in data.
Currently we are using java program for comparing data row by row and column by column and getting changes between data in rows with same UNIQUE KEY. it is working fine but taking too much time as we are having 100000 records in DB.
Now my question is : is there any way i can compare data at SQL level and get changes in data?
You can do it 'manually' with a query like this: It's a lot of work, but there are only three different types of checks you need to do, so it's not very complex:
select
*
from
Table1 t1
full outer join Table2 t2 on t2.ID = t1.ID
where
-- Check ID, either record does not exist in either table.
t1.ID is null or
t2.ID = null or
-- Not nullable field can be easily compared.
t1.NotNullableField1 <> t2.NotNUllableField1 or
-- Nullable field is slightly more work.
t1.NullableField1 <> t2.NullableField1 or
(t1.NullableField1 is null and t2.NullableField1 is not null) or
(t1.NullableField1 is not null and t2.NullableField1 is null)
Another solution is to use MINUS, which is a bit like UNION, only it returns a dataset minus the records in a second dataset:
select * from Table1 t1
MINUS
select * from Table2 t2
This works only one way (which might be fine for your purpose), but you can also combine it with UNION to make it bidirectional.
select
*
from
( select * from Table1
MINUS
select * from Table2)
UNION ALL
( select * from Table2
MINUS
select * from Table1)
The output of both solutions is a bit different.
In the FULL OUTER JOIN query, the IDs will be joined and the values of the matching rows will be displayed next to each other as a single row.
In the MINUS query, the result will be presented as a single dataset. If a record does not exist in either one table, it will be displayed. If a record (ID) exists in both tables, but other fields are different, you will get both rows. So it's a bit harder to compare them.
See: http://www.techonthenet.com/oracle/minus.php

CharIndex returning null when I know there is overlap in two strings

I have created a new column in my table(table1) . I am trying to populate it with data from another table, table2.
Table1 has a column called 'Name'. 'Name' contains a substring indicating the language of the column. I wish to compare this substring with the 'Language' column of table2, which contains the substring in the name column and insert the corresponding LanguageID into my new column.
So, for instance :
table1
Name
xxXxxxXxxxxxzxzxzxz xxxazxzxxXXXZxxzxzx 2183909213 ENG-UK nfjksdnfnd 723984782347
and table2 :
table2
Language | ID
ENG-uk | 1
In the table1 name column, the string before and after the Language can take any form, a varying number of characters. The language will always have a space before and after it.
So, I want to end up with :
table1
Name | LanguageID
xx... | 1
I have this query which I believe should work :
INSERT INTO table1 (LanguageID)
SELECT t2.ID FROM table2 t2, table1 t1 WHERE CHARINDEX(LOWER(t2.Language), LOWER(t1.Name)) != null
The problem is, when I run this...."(0 row(s) affected)", which should not be the case.
Does anyone have any ideas ?
The reason that you don't get any matches at all is that you can't use the != operator to compare null values, you have to use is not null for that.
However, that will give you a very big result, as the return value from charindex is never null. When the string isn't found it returns zero, so that is what you should compare against.
Also, you can't insert columns, you have to first add the column to the table, then update the records:
update t1
set LanguageID = t2.ID
from table1 t1
inner join table2 t2 on charindex(lower(t2.Language), lower(t1.Name)) != 0
1st, CHARINDEX returns 0 when search string does not exist. It doesn't do null.
See http://msdn.microsoft.com/en-us/library/ms186323.aspx
2nd, I think you should UPDATE, not INSERT.
example (this won't work correctly if t2.Language is not UNIQUE):
UPDATE table1 t1
SET t1.LanguageID = (SELECT t2.ID from table2 t2 where CHARINDEX(LOWER(t1.Name), LOWER(t2.Language))>0)
where exists (SELECT t2.ID from table2 t2 where CHARINDEX(LOWER(t1.Name), LOWER(t2.Language))>0)
You should consider adding individual columns for the first table information. Otherwise, you will end up with Performance Issues due to the SubString Operation.
It's clear from the first table that the table schema is not Normalized. Moreover, the First table schema is not suitable for any Search/Sorting operations.

Swap columns from two sql server tables

I would like to know if there is anyway I can compare two columns in SQL Server.
The two columns are located in two different tables.
When the column 1's value is smaller than the column 2's value:
I want to replace the value of the column 1 with the value of the column 2.
update table1 t1
set t1.col1 = (select t2.col2
from table2 t2
where t2.id = t1.id
and t1.col1 < t1.col2)
Something like that should do it easily.
The only tricky point I see is matching the row from table2 to the row from table1. In my example, I supposed both tables share an unique "id" column which enables easy matching. Modify the query with something more appropriate.
You should be able to do something like this:
update tablename set column1=column2
from table1 inner join table2 on joincondition
where column1 < column2;
Hard to be more spesific without the actual table structure.