How to get a row from a Table with no ids - sql

I have two tables, table A and table B, table A has and Id,a,b and c rows , Table B just has a,b and c and what i want (but i dont know how to do it) is to get a single row from Table B
(i would be something like comparinga,b,and c at the same time)
thanks!

SELECT A.id, B.a, B.b, B.c
FROM A
JOIN B
ON(A.a=B.a)
AND(A.b=B.b)
AND(A.c=B.c)
But I'd change your database structure and add foreign keyto table B referencing table A. It would really help you with this and later cases.

May I suggest changing your table structure.
TableA ( id primary key)
TableB(colA,colB,colC,fid foreign key refrencing TableA.id )
So now you dont have to store colA,colB,colC values in both TableA and TableB
Select B.*
From TableA A
Join TableB B
On A.id=B.fid

Related

Optimizing sql query: check for all rows in table B if any rows in table C reference the same row in table A

I have 3 tables, A, B and C structured like this
CREATE TABLE a (
id SERIAL NOT NULL PRIMARY KEY
);
CREATE TABLE b (
id SERIAL NOT NULL PRIMARY KEY,
a_id INT REFERENCES a(id) ON DELETE CASCADE
);
CREATE TABLE c (
id SERIAL NOT NULL PRIMARY KEY,
a_id INT REFERENCES a(id) ON DELETE CASCADE
);
Where the relationships are many-to-one. What i want is, for every row in table b, i want to check if any row in table c has a reference to the same row in table a. Now, I already have the query
SELECT
b.id,
true
FROM
b
WHERE EXISTS (
SELECT 1
FROM c
WHERE b.a_id = c.a_id
)
UNION
SELECT
b.id,
false
FROM
b
WHERE NOT EXISTS (
SELECT 1
FROM c
WHERE b.a_id = c.a_id
)
ORDER BY id
Though I am not certain, I think this is doing double work, and going through the table twice, and I am wondering how I could optimize it to only traverse the table once.
Is it possible with a simple query, or do I have to do anything complex?
Simply move the EXISTS clause into your SELECT clause.
SELECT
b.id,
EXISTS (SELECT null FROM c WHERE c.a_id = b.a_id) AS c_exists
FROM b;
The same with an IN clause, which I prefer for being even a tad simpler:
SELECT
id,
a_id IN (SELECT c.a_id FROM c) AS c_exists
FROM b;
This can be done with a subquery, a left join, and a case.
The subquery gets you a list of distinct c.a_id values.
SELECT DISTINCT a_id FROM c;
Then do this
SELECT b.id,
CASE WHEN distinct_ids.a_id IS NULL THEN 'false'
ELSE 'true' END has_c_row
FROM b
LEFT JOIN (
SELECT DISTINCT a_id FROM c;
) distinct_ids ON b.a_id = distinct_ids.a_id
This shape of query is called an antijoin or IS NULL ... LEFT JOIN. It detects the rows in the first table that don't match rows in the second table.
The subquery gives us a view of the data in table c with at most one row per each distinct a_id value. Without the subquery, we might get duplicate rows in the result query.
This eliminates your WHERE EXISTS correlated subqueries; even though PostgreSQL's query planner is pretty smart, sometimes it does the slow thing with subqueries like that.
If it is still too slow for you, create these indexes on the a_id columns.
ALTER TABLE b ADD INDEX a_id (a_id);
ALTER TABLE c ADD INDEX a_id (a_id);
i think i understand what you are after
this is how i would do it
SELECT b.id, ISNULL(res.result,0) as result
FROM b
LEFT JOIN (
SELECT c.id, 1 as result
FROM c
INNER JOIN a on a.id = c.id
) res on b.id = res.id
i dont think you need to worry about distinct if they are all unique ids

How to find what one table have elements of second table?

I have 2 Tables, that related with third by one-to-many relation.
For example I have Table A, Table B and Table C.
Table A and B related with table C as many-to-one. So in Table C I have 2 fields like tableAId and tableBId. As a result I need to find a list which includes all Elements from table C which related with table A and compare them to all elements from table C which related with table B.
I tried do it with except, minus statements, but it works incorrect.
Here is what I try to do:
SELECT tableAId FROM tableC
except
select tableBId FROM tableC
UPDATE
Here is my 3 tables :enter image description here
I'm not 100% following what you require but i think below is what you want
SELECT a.ID, b.ID
FROM TableA a
JOIN TableC c ON a.ID = c.TableCID
JOIN TableB b ON c.TableBID = b.ID

Inserting into one table from multiple tables except uniques

Lets say I have 3 tables named A,B and C
CREATE TABLE IF NOT EXIST A (ID integer primary key);
CREATE TABLE IF NOT EXIST B (ID integer primary key);
CREATE TABLE IF NOT EXIST C (IDA integer,IDB integer);
If I want to make sure that there is one C (and only one C) for every A,B pair. How do I do it?
I tried:
INSERT INTO C(IDA,IDB) SELECT A.ID, B.ID FROM A,B;
And it does create a C from each A,B pair. But if its run again it will be created again. How do I modify the query it so that it only creates a new C when there is not already a C with A and B.
Lets Say I have a:
A:1,2
B:1,2
C:(1,1),(1,2),(2,1),(2,2)
and then B=3 is added. I want a query that will add C:(1,3),(2,3) and not any pair already in C.
Please try this query. Hopefully it works for you.
INSERT INTO c (ida, idb)
SELECT DISTINCT a.id, b.id
FROM a, b
WHERE NOT EXISTS (SELECT 1
FROM c
WHERE c.ida = a.id
AND c.idb = b.id)
INSERT INTO C(IDA,IDB)
SELECT DISTINCT A.ID, B.ID
FROM A,B
MINUS
SELECT IDA, IDB
FROM C;
One another possible way, efficient if A & B are small as cartesian join is made.
You can set the table C:
CREATE TABLE IF NOT EXISTS C (IDA integer,IDB integer, UNIQUE (IDA, IDB) ON CONFLICT IGNORE);
SQLite will do all the work.

populate many to many table from existing tables

I have two existing tables with data populated
table A
--tableA_id
--contentA
table B
--tableB_id
--contentB
Now, I want to create a many to many relationship table
table A_B
--tableA_id
--tableB_id
the question is that how to write a sql script (I am new to sql) to populate table A_B using the existing data from table A and table B. Many thanks,
Mark
If you want to populate table A_B, you'd have to do this:
INSERT INTO A_B (tableA_id, tableB_id)
SELECT A.ID, B.ID FROM A CROSS JOIN B
CROSS JOIN will relate each row in table A with each row in table B.
If you want to relate some rows in table A with some rows in table B, you need to be more specific, and do something like:
INSERT INTO A_B (tableA_id, tableB_id)
SELECT A.ID, B.ID FROM A INNER JOIN B
ON A.some_field = B.some_other_field

SQL: Single select query from 2 Non-Joining tables

I have 2 tables which doesn't have any references to each other and I'm trying to create a third table (for reference lookup) by selecting from fields from both tables.
TableA has an A_ID
TableB has a B_ID
I want to create Table C which has a 1 to 1 reference between A_ID to B_ID
where A_ID = FirstID and B_ID = SecondID, I can't join the 2 tables because there's nothing in common.
Something like:
Insert INTO [TableC]
(FirstID, SecondID)
SELECT
A_ID As FirstID,
(Select B_ID From TableB)
FROM TableA
Basically we are creating a relationship right now with Table C so that we can use it to reference the two tables in the future using the their IDs.
Assuming TableA and TableB truly have nothing in common, then what you want is the Cartesian product, that is, for every row in A times every row in B.
INSERT INTO TableC(FirstID,SecondID)
SELECT A_ID,B_ID
FROM TableA
CROSS JOIN TableB
Perhaps what you really want is to join them by ROW_NUMBER().
INSERT INTO TableC(FirstID,SecondID)
SELECT A_ID,B_ID
FROM (SELECT A_ID,ROW_NUMBER() OVER (ORDER BY whatever) as rownumA FROM TableA) a
FULL OUTER JOIN (SELECT B_ID,ROW_NUMBER() OVER (ORDER BY whatever) as rownumB FROM TableB) b ON a.rownumA=b.rownumB