I have a database in SQL Server which contains huge numbers of tables. But each table has 'id' and 'value'. I want to join all the tables which their names contain a certain text (e.g., 'ts2') based on their id (id is a common key). So my desired table should have 'id' and the 'values' of each table with the name of the table. For example:
TableAts2:
id,
value
TableBts2:
id,
value
Tablts2C:
id,
value
...
My desired table:
mytable:
id, value_TableAts2,value_TableBts2, value_Tablts2C
Some source datatables
CREATE TABLE TableAts2 (id INT, value INT);
INSERT INTO TableAts2 VALUES (1,1), (2,2);
CREATE TABLE TableBts2 LIKE TableAts2;
INSERT INTO TableBts2 VALUES (1,11), (3,33);
CREATE TABLE TableCts2 LIKE TableAts2;
INSERT INTO TableCts2 VALUES (2,222), (3,333);
Build the query text
SELECT
CONCAT( 'SELECT id, ',
GROUP_CONCAT(table_name, '.value value_',table_name) ,
'\nFROM (',
GROUP_CONCAT('SELECT id FROM ',table_name SEPARATOR ' UNION '),
') ids\nLEFT JOIN ',
GROUP_CONCAT(table_name, ' USING (id)' SEPARATOR '\nLEFT JOIN ')
)
INTO #sql
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = DATABASE();
Check the query built
SELECT #sql;
SELECT id, TableAts2.value value_TableAts2,TableBts2.value value_TableBts2,TableCts2.value value_TableCts2
FROM (SELECT id FROM TableAts2 UNION SELECT id FROM TableBts2 UNION SELECT id FROM TableCts2) ids
LEFT JOIN TableAts2 USING (id)
LEFT JOIN TableBts2 USING (id)
LEFT JOIN TableCts2 USING (id)
Execute the query
PREPARE stmt FROM #sql;
EXECUTE stmt;
DROP PREPARE stmt;
id
value_TableAts2
value_TableBts2
value_TableCts2
1
1
11
null
2
2
null
222
3
null
33
333
db<>fiddle here
Of course the query needs in a check that the table contains both id and value columns (by according subquery to INFORMATION_SCHEMA.COLUMNS).
i think this should work fine for you :
select tableAts1.* , TableBts2.* , Tablts2C.*
from tableAts1
inner join TableBts2 on tableAts.id = TableBts2.id
inner join Tablts2C on tableBts2.id = tablts2C.id
First, you need to insert one column in each table.
For example
TableAts2:
id,
user_id,
value
TableBts2:
id,
user_id,
value
Tablts2C:
id,
user_id,
value
...
Second, you need to join each table with user_id.
Now please run this sql command:
select t.value_TableAts2 as value_TableAts2, t.value_TableBts2 as value_TableBts2, Tablts2C.value as value_Tablts2C from (select TableAts2.value as value_TableAts2, TableBts2.value as value_TableBts2, TableAts2.user_id as user_id from TableAts2 left join TableBts2 on TableAts2.user_id = TableBts2.user_id) as t left join Tablts2C on t.user_id = Tablts2C.user_id
Result :::
Your desired table:
id, value_TableAts2,value_TableBts2, value_Tablts2C
Related
I have the following SQL:
SELECT id, user_id, coordinates
FROM fields
WHERE id IN (SELECT field_id FROM transactions WHERE id IN (11,10,12))
There are 2 tables: transactions and fields. Both of them have their own id field. However, in transactions there's also a field to connect each row to the fields.id called field_id. I have a list of transactions.id, and I would like to obtain a few fields from table fields, but I would like to obtain too the transactions.id associated. For example for the first row it would be:
fields.id (for transactions.id=11), fields.user_id (for transactions.id=11), fields.coordinates (for transactions.id=11), 11
and so on.
Is this possible? I will do these queries using python with postgresql v14.
If I understood the question correctly
SELECT * FROM fields f
join transactions t on f.id = t.field_id
WHERE t.id in (11,10,12)
SELECT t.id as lower_id, f.id as higher_id FROM fields f
join transactions t on f.id = t.field_id
WHERE t.id in (11,10,12)
I have a dataset of million entries, its comprised of songs and their artists.
I have
a track_id
an artist_id.
There are 3 tables
tracks (track_id, title, artist_id),
artists(artist_id and artist_name) and
artist_term (artist_id and term).
Using only one query, I have to count the number of tracks whose artists don't have any linked terms.
For more reference, the schema of the DB is as follows:
CREATE TABLE tracks (track_id text PRIMARY KEY, title text, release text, year int, duration real, artist_id text);
CREATE TABLE artists (artist_id text, artist_name text);
CREATE TABLE artist_term (artist_id text, term text, FOREIGN KEY(artist_id)
REFERENCES artists(artist_id));
How do I get to the solution? please help!
You can use not exists:
select count(*) cnt
from tracks t
where not exists (select 1 from artist_term at where at.artist_id = t.artist_id)
As far as concerns you do not need to bring in the artists table since artist_id is available in both tracks and artist_term tables.
For performance you want an index on tracks(artist_id) and another one on artist_term(artist_id).
An anti-left join would also get the job done:
select count(*) cnt
from tracks t
left join artist_term at on at.artist_id = t.artist_id
where at.artist_id is null
You can join the tables tracks and artists and left join the table artist_term so to find the unmatched artist_ids:
select count(distinct t.track_id)
from tracks t
inner join artists a on a.artist_id = t.artist_id
left join artist_term at on at.artist_id = a.artist_id
where at.artist_id is null
The condition at.artist_id is null in the WHERE clause will return only the unmatched rows which will be counted.
If I'm not mistaken, such a query could be built in a similar fashion like its sibling SQL languages. If so, it should look something like this:
SELECT COUNT(track_id)
FROM tracks as t
WHERE EXISTS (
SELECT *
FROM artists AS a
WHERE a.artist_id = t.artist_id
AND NOT EXISTS(
SELECT *
FROM artist_term as at
WHERE at.artist_id = a.artist_id
)
)
So this query basically says: count the number of different tracks (marked by their unique track_id), where there is an artist that has the same artist_id, where no artist_term exists that refers to the artist_id of the artist.
Hope this helps!
I have table_A with two columns:
create table table_a(id int, data json);
A row could be:
insert into table_a values
(1, '{"name": "kate", "cellphone": "000-000-0000", "address": "some text here"}');
I want to write a function that will take a row from table_A and insert a new row into table_B. Table_B has columns: id integer, name VARCHAR, cellphone VARCHAR, address TEXT, additional_info TEXT.
So my function should parse json field and put each value in the corresponding column of the Table_B (assume that all possible columns exist in Table_B).
It looks like I can use json_to_record(json), but how can I insert returned values into Table_B?
I am using PyGreSQL to connect with my database.
You should use the function in a lateral join. A column definition list should be added as the function returns record.
select id, r.*
from table_a
cross join lateral
json_to_record(data)
as r(name varchar, cellphone varchar, address text, additional_info text)
id | name | cellphone | address | additional_info
----+------+--------------+----------------+-----------------
1 | kate | 000-000-0000 | some text here |
(1 row)
The insert statement may look like this:
insert into table_b
select id, r.*
from table_a
cross join lateral
json_to_record(data)
as r(name varchar, cellphone varchar, address text, additional_info text)
This worked for me
insert into customers(firstName, lastName,email)
select r."firstName", r."lastName",email
from json_to_record('{"firstName": "fn","lastName":"ln","email":"e#theRevelationSquad.com"}')
as r("firstName" varchar, "lastName" varchar, email text);
This is my query using code found perusing this site:
query="""SELECT Family
FROM Table2
INNER JOIN Table1 ON Table1.idSequence=Table2.idSequence
WHERE (Table1.Chromosome, Table1.hg19_coordinate) IN ({seq})
""".format(seq=','.join(['?']*len(matchIds_list)))
matchIds_list is a list of tuples in (?,?) format.
It works if I just ask for one condition (ie just Table1.Chromosome as oppose to both Chromosome and hg_coordinate) and matchIds_list is just a simple list of single values, but I don't know how to get it to work with a composite key or both columns.
Since you're running SQLite 3.7.17, I'd recommend to just use a temporary table.
Create and populate your temporary table.
cursor.executescript("""
CREATE TEMP TABLE control_list (
Chromosome TEXT NOT NULL,
hg19_coordinate TEXT NOT NULL
);
CREATE INDEX control_list_idx ON control_list (Chromosome, hg19_coordinate);
""")
cursor.executemany("""
INSERT INTO control_list (Chromosome, hg19_coordinate)
VALUES (?, ?)
""", matchIds_list)
Just constrain your query to the control list temporary table.
SELECT Family
FROM Table2
INNER JOIN Table1
ON Table1.idSequence = Table2.idSequence
-- Constrain to control_list.
WHERE EXISTS (
SELECT *
FROM control_list
WHERE control_list.Chromosome = Table1.Chromosome
AND control_list.hg19_coordinate = Table1.hg19_coordinate
)
And finally perform your query (there's no need to format this one).
cursor.execute(query)
# Remove the temporary table since we're done with it.
cursor.execute("""
DROP TABLE control_list;
""")
Short Query (requires SQLite 3.15): You actually almost had it. You need to make the IN ({seq}) a subquery
expression.
SELECT Family
FROM Table2
INNER JOIN Table1
ON Table1.idSequence = Table2.idSequence
WHERE (Table1.Chromosome, Table1.hg19_coordinate) IN (VALUES {seq});
Long Query (requires SQLite 3.8.3): It looks a little complicated, but it's pretty straight forward. Put your
control list into a sub-select, and then constrain that main select by the control
list.
SELECT Family
FROM Table2
INNER JOIN Table1
ON Table1.idSequence = Table2.idSequence
-- Constrain to control_list.
WHERE EXISTS (
SELECT *
FROM (
SELECT
-- Name the columns (must match order in tuples).
"" AS Chromosome,
":1" AS hg19_coordinate
FROM (
-- Get control list.
VALUES {seq}
) AS control_values
) AS control_list
-- Constrain Table1 to control_list.
WHERE control_list.Chromosome = Table1.Chromosome
AND control_list.hg19_coordinate = Table1.hg19_coordinate
)
Regardless of which query you use, when formatting the SQL replace {seq} with (?,?) for each compsite
key instead of just ?.
query = " ... ".format(seq=','.join(['(?,?)']*len(matchIds_list)))
And finally flatten matchIds_list when you execute the query because it is a list of tuples.
import itertools
cursor.execute(query, list(itertools.chain.from_iterable(matchIds_list)))
I need to update a field with a value from another table in MySQL, using Python Connector (not that important though). I need to select a value from one table based on a matching criteria and insert the extracted column back into the previous table based on the same matching criteria.
I have the following, which doesn't work of cource.
for match_field in list:
cursor_importer.execute(UPDATE table1 SET table1_field =
(SELECT field_new FROM table2 WHERE match_field = %s)
WHERE match_field = %s LIMIT 1,
(match_field, match_field ))
You can use UPDATE with JOINS.
Below is an example in MySQL:
UPDATE table1 a JOIN table2 b ON a.match_field = b.match_field
SET a.table1_field = b.field_new
WHERE a.match_field = 'filter criteria'