I have table1 with columns A , B , C and another one, table2 with columns A, D.
I want to create a view to show columns A, B, C, D and there should be all values of column A even if there is no A in table2
I tried:
select
a, b, c, d
from
table 1
inner join
table 2 where table1.a = table2.a
suggest something
You will want to use an OUTER JOIN:
SELECT t1.a, t1.b, t1.c, t2.d
FROM table t1
LEFT JOIN table t2
ON t1.a = t2.a;
Related
This seems like a rather straightforward problem, yet I have not been able to find the solution:
In a table test, I have some subset of columns which I am interested in, say a,b,c,d,e,f.
Some or most of these columns are NULL, but at least one is always filled.
Now for some rows, returned, say by:
SELECT rowid,a,b,c,d,e,f LIMIT 1;
I would like to get the number of rows which have the same non-null values.
So for example if a,d,f are the columns that are not NULL for this row, the result would be the same as for:
SELECT COUNT(*)
FROM test WHERE a=a_ AND d=d_ AND f=f_
SELECT a as a_, d as d_, f as f_ FROM test LIMIT 1;
How can this be done in one step / line? Or do I need a temporary table?
You can use the operator IS to compare safely values that may be NULL:
SELECT COUNT(*)
FROM test t1
INNER JOIN (SELECT a, b, c, d, e, f FROM test LIMIT 1) t2
ON (t1.a, t1.b, t1.c, t1.d, t1.e, t1.f) IS (t2.a, t2.b, t2.c, t2.d, t2.e, t2.f);
or with a CTE:
WITH cte AS (SELECT a, b, c, d, e, f FROM test LIMIT 1)
SELECT COUNT(*)
FROM test t1 INNER JOIN cte t2
ON (t1.a, t1.b, t1.c, t1.d, t1.e, t1.f) IS (t2.a, t2.b, t2.c, t2.d, t2.e, t2.f);
See the demo.
In SQLite, I have the following query
SELECT x.nameIndex, y.nameIndex
FROM relation x, relation y
WHERE x.label=y.label AND x.feature=1 AND y.feature=0;
which returns all pairs of x.nameIndex,y.nameIndex with the same label where x has feature 1 and y has feature 0.
Now I have another table index2name where I store the name for each index, where I could do like:
SELECT name FROM index2name WHERE nameIndex=...;
How can I change the top query such that it looks up the name for the respective indeces and returns pairs of names instead?
Use a CTE which returns the name instead of the indexes and the group for each row in relation (by a join to index2name) and do a self join on that:
WITH cte AS (
SELECT i.name, r.label, r.feature
FROM relation r INNER JOIN index2name i
ON i.nameIndex = r.nameIndex
)
SELECT c1.name, c2.name
FROM cte c1 INNER JOIN cte c2
ON c2.label = c1.label
WHERE c1.feature=1 AND c2.feature=0;
Or without the CTE:
SELECT i1.name, i2.name
FROM relation r1 INNER JOIN relation r2
ON r2.label = r1.label
INNER JOIN index2name i1 ON i1.nameIndex = r1.nameIndex
INNER JOIN index2name i2 ON i2.nameIndex = r2.nameIndex
WHERE r1.feature=1 AND r2.feature=0;
I need any help getting data from three tables.
This is my setup:
TableA with two columns: id, name
TableB with three columns: id_a, id_c1, id_c2
TableC with two columns: id, name
I want as result the following table:
TableA.name,TableC.name,TableC.name
where the TableC.name(s) are expansion of id_c1, id_c2 of TableB.
Any idea?
Very thanks
You need to join the 3 tables like this:
select a.name, c1.name, c2.name
from tablea a inner join tableb b
on b.id_a = a.id
inner join tablec c1
on c1.id = b.id_c1
inner join tablec c2
on c2.id = b.id_c2
Maybe instead of inner joins you need left joins, but I can't tell for sure.
I need to perform a recursive count operation on tables but here are the challenges that I am facing with.
Lets say I have tables A, B, C, D, E, F, .... Z
Here is the code snippet of what I have,
Proc sql;
create table temp as(
select count(*)
from a
inner join b on a.id = b.id
inner join c on a.id = c.id
inner join d on a.id = d.id
where <condition>
);
Once this code is complete I need to run the same query with B, C, D and E and update the result in same temp table that I am trying to create. This way I have to do for the entire table list that I have.
Is there a recursive sql to do this. I don't require a separate macro to call the query each time with different tables.
I would not do it quite this way.
proc sql;
create table temp as (
select count(case when n(a.id,b.id,c.id,d.id)=4 then 1 else 0 end) as abcd_count,
count(case when n(b.id,c.id,d.id,e.id)=4 then 1 else 0 end) as bcde_count
from a outer join b on a.id=b.id
outer join c ... etc.
;
quit;
IE, just do one join and use case when... to determine what has the counts you need. Here I use n() to identify records with all 4 ids on them.
I am attempting to respond to the insertion of a row in one table (A) to create or update multiple rows in a second table (B) based on the values of a third table (C) (which can be joined to the first).
I have the following construct,
CREATE TRIGGER MyTrigger AFTER INSERT ON A
BEGIN
INSERT OR REPLACE INTO B (ID, T1, T2, Role)
VALUES
(
( SELECT ID FROM C WHERE R1 = NEW.R1 ),
NEW.T1,
B.T2, -- The existing row's T2
( SELECT Role FROM C WHERE R1 = NEW.R1 ),
)
END;
Table A has columns ID, T1, R1
Table B has columns ID, T1, T2, Role
Table C has columns ID, R1, R2, Role
I have at least two problems with my attempts at composing the trigger
I don't know how to reference B's existing values in the REPLACE case, thus the "B.T2"
I don't know how to reference multiple columns (R1, Role) from the same row in table C when doing my INSERT/REPLACE in table B.
Thanks for any help in sorting this out.
Using SELECT instead of VALUES:
CREATE TRIGGER MyTrigger AFTER INSERT ON A BEGIN
INSERT OR REPLACE INTO B (ID, T1, T2, Role) SELECT
(SELECT ID FROM C WHERE R1 = NEW.R1),
NEW.T1,
B.T2,
(SELECT Role FROM C WHERE R1 = NEW.R1)
FROM B WHERE ROWID=NEW.ROWID
END;
I was able to use a LEFT OUTER JOIN on the SELECT so that all the needed values can be named regardless of whether there's an existing row.
CREATE TRIGGER MyTrigger AFTER INSERT ON A
BEGIN
INSERT OR REPLACE INTO B (ID, T1, T2, Role)
SELECT
C.ID,
NEW.T1,
B.T2,
C.Role
FROM C LEFT OUTER JOIN B ON C.ID = B.ID WHERE C.R1 = NEW.R1;
END;
To find the B record, just use a subquery like you're doing with C.
The B.ID value to search for is the same as that you're trying to insert.
CREATE TRIGGER MyTrigger
AFTER INSERT ON A
BEGIN
INSERT OR REPLACE INTO B (ID, T1, T2, Role)
VALUES
(
( SELECT ID FROM C WHERE R1 = NEW.R1 ),
NEW.T1,
( SELECT T2 FROM B WHERE ID = ( SELECT ID FROM C WHERE R1 = NEW.R1 ) ),
( SELECT Role FROM C WHERE R1 = NEW.R1 )
);
END;