Querying Same Lookup Table With Multiple Columns - sql

I'm a bit confused on this. I have a data table structured like this:
Table: Data
DataID Val
1 Value 1
2 Value 2
3 Value 3
4 Value 4
Then I have another table structured like this:
Table: Table1
Col1 Col2
1 2
3 4
4 3
2 1
Both columns from Table1 point to the data in the data table. How can I get this data to show in a query? For example, a query to return this:
Query: Query1
Column1 Column2
Value 1 Value 2
Value 3 Value 4
Value 4 Value 3
Value 2 Value 1
I'm familiar enough with SQL to do a join with one column, but lost beyond that. Any help is appreciated. Sample sql or a link to something to read. Thanks!
PS: This is in sqlite

You can join the same table twice:
Select
d1.val As column1,
d2.val As column2
From table1 t
Join data d1 On ( d1.dataId = t.col1 )
Join data d2 On ( d2.dataId = t.col2 )

Related

Combine three columns from different tables into one row

I am new to sql and are trying to combine a column value from three different tables and combine to one row in DB2 Warehouse on Cloud. Each table consists of only one row and unique column name. So what I want to is just join these three to one row their original column names.
Each table is built from a statement that looks like this:
SELECT SUM(FUEL_TEMP.FUEL_MLAD_VALUE) AS FUEL
FROM
(SELECT ML_ANOMALY_DETECTION.MLAD_METRIC AS MLAD_METRIC, ML_ANOMALY_DETECTION.MLAD_VALUE AS FUEL_MLAD_VALUE, ML_ANOMALY_DETECTION.TAG_NAME AS TAG_NAME, ML_ANOMALY_DETECTION.DATETIME AS DATETIME, DATA_CONFIG.SYSTEM_NAME AS SYSTEM_NAME
FROM ML_ANOMALY_DETECTION
INNER JOIN DATA_CONFIG ON
(ML_ANOMALY_DETECTION.TAG_NAME =DATA_CONFIG.TAG_NAME AND
DATA_CONFIG.SYSTEM_NAME = 'FUEL')
WHERE ML_ANOMALY_DETECTION.MLAD_METRIC = 'IFOREST_SCORE'
AND ML_ANOMALY_DETECTION.DATETIME >= (CURRENT DATE - 9 DAYS)
ORDER BY DATETIME DESC)
AS FUEL_TEMP
I have tried JOIN, INNER JOIN, UNION/UNION ALL, but can't get it to work as it should. How can I do this?
Use a cross-join like this:
create table table1 (field1 char(10));
create table table2 (field2 char(10));
create table table3 (field3 char(10));
insert into table1 values('value1');
insert into table2 values('value2');
insert into table3 values('value3');
select *
from table1
cross join table2
cross join table3;
Result:
field1 field2 field3
---------- ---------- ----------
value1 value2 value3
A cross join joins all the rows on the left with all the rows on the right. You will end up with a product of rows (table1 rows x table2 rows x table3 rows). Since each table only has one row, you will get (1 x 1 x 1) = 1 row.
Using UNION should solve your problem. Something like this:
SELECT
WarehouseDB1.WarehouseID AS TheID,
'A' AS TheSystem,
WarehouseDB1.TheValue AS TheValue
FROM WarehouseDB1
UNION
SELECT
WarehouseDB2.WarehouseID AS TheID,
'B' AS TheSystem,
WarehouseDB2.TheValue AS TheValue
FROM WarehouseDB2
UNION
WarehouseDB3.WarehouseID AS TheID,
'C' AS TheSystem,
WarehouseDB3.TheValue AS TheValue
FROM WarehouseDB3
Ill adapt the code with your table names and rows if you tell me what they are. This kind of query would return something like the following:
TheID TheSystem TheValue
1 A 10
2 A 20
3 B 30
4 C 40
5 C 50
As long as your column names match in each query, you should get the desired results.

bigQuery assign a value to table 1 based on table 2

I would like to update Table 2 based based on Table 1 that is given by:
Row sample_id PIK3CA_features
1 huDBF9DD chr3_3268035_CT
2 huDBF9DD chr3_3268043_AT
3 huDBF9DD chr3_3268049_T
Table 2:
Row sample_id chr3_3268035_CT chr3_3268043_AT chr3_3268049_C
1 huDBF9DD 1 1 null
2 huDBF9De null null null
3 huDBF9Dw null null null
For each row in Table 1, if its samle_id is correspondent in Table 2 then I'd like to update the respective PIK3CA_feature in Table 2 to 1.
How can I pass the sample_id and PIK3CA_features values from Table 1 as parameters to update Table 2 in a SQL command?
You can use an UPDATE statement to accomplish this. Assuming I understand correctly, you want something like this query:
#standardSQL
UPDATE table2 AS t2
SET
chr3_3268035_CT =
IF(t1.PIK3CA_features = 'chr3_3268035_CT', 1, chr3_3268035_CT),
chr3_3268043_AT =
IF(t1.PIK3CA_features = 'chr3_3268043_AT', 1, chr3_3268043_AT),
chr3_3268049_C =
IF(t1.PIK3CA_features = 'chr3_3268049_C', 1, chr3_3268049_C)
FROM table1 AS t1
WHERE true;
This will set the appropriate column in table 2 to have a value of 1 based on the value of PIK3CA_features. If you have a lot of these columns, you can generate the query using Python or some other programming language, or you can generate all the column_name=expression pairs using a query:
#standardSQL
SELECT
STRING_AGG(FORMAT('%s=IF(t1.PIK3CA_features="%s",1,%s)',
PIK3CA_features, PIK3CA_features, PIK3CA_features), ',\n')
FROM (
SELECT DISTINCT PIK3CA_features
FROM table1
);
This produces a list like:
chr3_3268035_CT=IF(t1.PIK3CA_features="chr3_3268035_CT",1,chr3_3268035_CT),
chr3_3268049_C=IF(t1.PIK3CA_features="chr3_3268049_C",1,chr3_3268049_C),
chr3_3268043_AT=IF(t1.PIK3CA_features="chr3_3268043_AT",1,chr3_3268043_AT)

Comparing two tables and get the values that dont match

I have two tables with articles.
table 1 article and table 2 articlefm
both tables have one field with artnr.
'table 1' has 2192 artnr and 'table 2' has 2195 artnr.
I want in my query to find out whats the artnr of the 3 articles that is not matched.
If 'table 2' has more articles then 'table 1' then I need a list with those artnr.
How can I make this?
You can do this using a FULL JOIN:
SELECT COALESCE(t1.Artnr, t2.Artnr) AS Artnr,
CASE WHEN t1.Artnr IS NULL THEN 'Table1' ELSE 'Table2' END AS MissingFrom
FROM Table1 AS t1
FULL JOIN Table2 AS t2
ON t1.Artnr = t2.Artnr
WHERE t1.Artnr IS NULL
OR t2.Artnr IS NULL;
Note, that just because there is a difference in the count of 3, it does not necessarily mean that there are only 3 records in one table missing from the other. Imagine the following:
Table1 Table2
------ -------
1 2
2 4
3 6
4
The difference in count is 1, but there are actually 2 records present in table1 that aren't in table2, and 1 in table2 that isn't in table1. Using the above full join method you would get a result like:
Artnr | MissingFrom
------+-------------
1 | Table1
3 | Table1
6 | Table2
In most databases you can use except (SQL standard) or minus (Oracle specific):
select artnr
from articlefm -- table 2
except
select artnr
from article -- table 1
Else you could try a not in:
select atrnr
from articlefm -- table 2
where atrnr not in
( select artnr
from article -- table 1
)
This will give you the article numbers that exist in 2, but not in 1.

SQL Derby return middle of table

Say I have a table that looks something like this
COL1
1
1
1
2
2
3
3
3
3
4
5
5
6
6
7
7
With some other columns that are unimportant for this question. If I want to return all but the first two values from 4 how would I do this with derby?
Here is the expected output to clear up what I'm wanting
COL1
3
3
3
3
4
5
5
6
6
Thanks for the help, I'm not the best with SQL but I'm trying :)
try this...
SELECT t.*
FROM mytab t
INNER JOIN (SELECT MIN(COL1) AS VAL2
FROM mytab
WHERE COL1 NOT IN (SELECT MIN(COL1) FROM mytab)) x
ON t.COL1 > x.VAL2
working example at
http://www.datagloop.com/?USERNAME=DATAGLOOP/SO_DERBY&ACTION=LOGIN
Here is a solution that uses a temporary table that allows more flexibility, readability and also allows you to tune the parameters better.
The ROWID part of the queries is your position reference.
CREATE TEMP TABLE mycol_order
(COL1 INTEGER NOT NULL,
TOTAL_COLS INTEGER NOT NULL,
PRIMARY KEY (COL1));
INSERT INTO mycol_order
(COL1,TOTAL_COLS)
SELECT DISTINCT t1.COL1,
t2.total
FROM mytab t1,
(SELECT COUNT(DISTINCT COL1) AS total FROM mytab) t2
ORDER BY 1;
SELECT t.*
FROM mytab t
INNER JOIN mycol_order co
ON co.col1 = t.col1
AND co.ROWID > 2
AND co.ROWID < co.total_cols;
Also updated the working example at
working example at http://www.datagloop.com/?USERNAME=DATAGLOOP/SO_DERBY&ACTION=LOGIN

return IDs that have ALL of a list of correpsonding values

I have table with 2 columns ....
id id2
1 1
1 2
1 3
2 1
2 2
2 4
3 2
3 3
3 4
I want to return the ids which have for example id2 in (1, 2, 4) but that has all of the values in the list.
In this above case it would return id = 2. Is this possible?
select id
from MyTable
where id2 in (1, 2, 4)
group by id
having count(distinct id2) = 3 --this must match the number of elements in IN clause
Update:
If the list of IDs is variable, then you should create an additional table that contains the varying sets of IDs, which you can then JOIN against to do your filtering.
Are you alluding to relational division? e.g. the supplier who supplies all products, the pilot that can fly all the planes in the hanger, etc?
If so, this article has many example implementations in SQL.
Do a self-join to test different rows on the same table in one go:
SELECT id
FROM t AS t0
JOIN t AS t1 ON t1.id=t0.id
JOIN t AS t2 ON t2.id=t1.id
WHERE t0.id2=1
AND t1.id2=2
AND t2.id2=4