Following CROSS JOIN how to remove records comparing same record - cross-join

I have done a CROSS JOIN, comparing each record to all other records.
However, I want to remove those where the same record is being compared.
What is the most efficient way to do this?

Is this what you are looking for?
SELECT *
FROM Table1
CROSS JOIN Table2
WHERE Table1.PrimaryKey <> Table2.PrimaryKey

Not exactly sure if you are looking to remove the records from both tables whenever there are duplicates, but here is how I would do it.
CREATE TABLE #TableA
(
PK_A INT IDENTITY(1,1) NOT NULL,
Field1 INT,
Field2 VARCHAR(20),
Field3 BIT
)
INSERT INTO #TableA (Field1, Field2, Field3) VALUES (1, 'A', 0), (1, 'B', 1), (2, 'C', 1), (3, 'C', 0)
CREATE TABLE #TableB
(
PK_B INT IDENTITY(10,10) NOT NULL,
Field1 INT,
Field2 VARCHAR(20),
Field3 BIT
)
INSERT INTO #TableB (Field1, Field2, Field3) VALUES (1, 'A', 1), (1, 'B', 1), (2, 'C', 1), (3, 'C', 1)
SELECT * FROM #TableA;
SELECT * FROM #TableB;
DECLARE #pks AS TABLE
(
PK_A INT,
PK_B INT
)
INSERT INTO #pks (PK_A, PK_B)
SELECT PK_A, PK_B
FROM #TableA INNER JOIN #TableB
ON #TableA.Field1 = #TableB.Field1
AND #TableA.Field2 = #TableB.Field2
AND #TableA.Field3 = #TableB.Field3
DELETE FROM #TableA WHERE PK_A IN (SELECT PK_A FROM #pks)
DELETE FROM #TableB WHERE PK_B IN (SELECT PK_B FROM #pks)
SELECT * FROM #TableA;
SELECT * FROM #TableB;
DROP TABLE #TableA;
DROP TABLE #TableB;

Related

How are primary keys autoassigned in sqlite3?

I'm writing a node application using an sqlite3 db. Does anyone know, if I do an insert of multiple records, are the primary IDs autoassigned in the order the statements are given?
That is, for table with columns
`id` INTEGER PRIMARY KEY,
`field1` INTEGER,
`field2` INTEGER
I submit a statement like:
INSERT INTO table (field1, field2) VALUES (1, 2), (2, 3), (3, 4), (4, 5), (5, 6);
If in the callback this.lastID is 20. Can I assume the rows are (16, 1, 2), ... (20, 5, 6)?
I've experimented with this and found that the ID always seems to be assigned this way, but is it reliable?
What if I also know that this.lastID was 15 before the insert, so I know the IDs are [15, ..., 20]?
For extra credit, same question if I submit the inserts separately and run the queries asynchronously: can I rely on the IDs being assigned in the order the statements were passed?

Python sqlite3: Loop through rows from table_a stops when inserting into table_b

Trying to to loop through rows from table_a, pass them into a function, and insert the outputs into table_b. I can manage to loop through rows from table_a, but as soon as i try to insert to table_b something, my script just stops.
with sqlite3.connect(db_path) as db:
cursor = db.cursor()
cursor.execute("""SELECT * FROM cars""")
for row in cursor:
car_price = get_car_price(row[0])
cursor.execute("""INSERT INTO car_prices (price, car_id) VALUES (?,?);""",(car_price, row[0]))
output :
[Finished in 1.0s]
It is weird because the below works, but as soon as i try executing to car_prices table (as in the previous code), the code just ends at first iteration.
with sqlite3.connect(db_path) as db:
cursor = db.cursor()
cursor.execute("""SELECT * FROM cars""")
for row in cursor:
print(row)
output:
(1, "car_1")
(2, "car_2")
...
(n, "car_n")
[Finished in 0.7s]
As asked, here is the .schema:
sqlite> .schema
CREATE TABLE IF NOT EXISTS "cars" (
"id" integer NOT NULL,
"name" text NOT NULL,
"website_url" text NOT NULL,
PRIMARY KEY("id")
);
CREATE TABLE IF NOT EXISTS "car_prices" (
"price_id" integer,
"price" NUMERIC NOT NULL,
"car_id" integer NOT NULL,
PRIMARY KEY("price_id"),
FOREIGN KEY("car_id") REFERENCES "cars"("id")
The problem is that you're reusing your cursor, throwing away the results of your first query.
Here's a minimal runnable example (you may have gotten a faster answer if you had included this in your question, since it would've taken less effort for people to get involved):
#!/usr/bin/env python3
import sqlite3
import sys
def get_car_price(carid):
return carid * 11 + 101
with sqlite3.connect(':memory:') as db:
db.execute('''
CREATE TABLE IF NOT EXISTS "cars" (
"id" integer NOT NULL,
"name" text NOT NULL,
"website_url" text NOT NULL,
PRIMARY KEY("id")
)
''')
db.execute('''
CREATE TABLE IF NOT EXISTS "car_prices" (
"price_id" integer,
"price" NUMERIC NOT NULL,
"car_id" integer NOT NULL,
PRIMARY KEY("price_id"),
FOREIGN KEY("car_id") REFERENCES "cars"("id")
)
''')
for ix, name in enumerate(('Lolvo', 'Yotoya', 'Edison')):
url = 'http://example.com/' + name.lower()
db.execute('INSERT INTO cars VALUES(?,?,?)', (ix, name, url))
cursor = db.cursor()
if 'sep' in sys.argv:
insertcursor = db.cursor()
else:
insertcursor = cursor
cursor.execute("""SELECT * FROM cars""")
for row in cursor:
car_price = get_car_price(row[0])
print(row, car_price)
insertcursor.execute("""INSERT INTO car_prices (price, car_id) VALUES (?,?);""",(car_price, row[0]))
cursor.execute('''SELECT * FROM car_prices''')
for row in cursor:
print('car_prices:', row)
Running with no args, it'll use the same cursor, reproducing your problem:
python-sqlite-stops$ ./stuff.py
(0, 'Lolvo', 'http://example.com/lolvo') 101
car_prices: (1, 101, 0)
Give it 'sep' as an arg, and it'll use a separate cursor for insertion, fixing your problem:
python-sqlite-stops$ ./stuff.py sep
(0, 'Lolvo', 'http://example.com/lolvo') 101
(1, 'Yotoya', 'http://example.com/yotoya') 112
(2, 'Edison', 'http://example.com/edison') 123
car_prices: (1, 101, 0)
car_prices: (2, 112, 1)
car_prices: (3, 123, 2)
You could make it even simpler by just using db.execute() for the inserts; no cursor() call necessary.

What is the correct way to insert data into a Cassandra UDT?

Here is the type I have created,
CREATE TYPE urs.dest (
destinations frozen<list<text>>);
And here is the table ,
CREATE TABLE urs.abc (
id int,
locations map<text, frozen<dest>>,
PRIMARY KEY(id));
When I try to insert values from cqlsh,
try 1:
insert into urs.abc (id, locations ) values (1, {'coffee': { 'abcd', 'efgh'}});
try 2:
insert into urs.abc (id, locations ) values (1, {'coffee': ['abcd', 'efgh']});
try 3:
insert into urs.abc (id) values (1);
update urs.abc set locations = locations + {'coffee': {'abcd','qwer'}} where id=1;
I'm getting the below error,
Error from server: code=2200 [Invalid query] message="Invalid map literal for locations: value {'abcd', 'qwer'} is not of type frozen<dest>"
Can anyone please let me know the correct way to add value to my UDT?
Table creation seems fine
To insert to the table to urs.abc use this
insert into urs.abc (id, locations ) values (1, {'coffee':{ destinations: ['abcd', 'efgh']}});
You are missing the field name destinations.

How to make sqlite3 module not converting column data to integer type

I'm trying to read data from a sqlite3 database using python3 and it looks as it tries to be smart and convert columns looking like a integer to integer type. I don't want that (if I got it right sqlite3 stores data as text no matter what anyway).
I've created the database as:
sqlite> create table t (id integer primary key, foo text, bar datetime);
sqlite> insert into t values (NULL, 1, 2);
sqlite> insert into t values (NULL, 1, 'fubar');
sqlite> select * from t;
1|1|2
2|1|fubar
and tried to read it using:
db = sqlite3.connect(dbfile)
cur = db.cursor()
cur.execute("SELECT * FROM t")
for l in cur:
print(t)
db.close()
And getting output like:
(1, '1', 2)
(2, '1', 'fubar')
but I expected/wanted something like
('1', '1', '2')
('2', '1', 'fubar')
(definitely for the last column)
Try
for l in cur:
print((str(x) for x in t))
SQLite stores values in whatever affinity the column has.
If you do not want to have numbers, don't use datetime but text.

How to do multiget in CQL3 for composite row key?

CF schema:
CREATE TABLE mytable (
upperId int,
lowerId int,
hour timestamp,
counter text,
succ int,
fail int,
PRIMARY KEY ((upperId, lowerId), hour, counter));
each record is keyed by composite id upperId:lowerid, how can I do multiget with CQL3?
This is not valid:
select * from mytable where (upperid, lowerid) in ((10000, 1), (10000, 2), (20000, 1));
I can't do this either:
select * from mytable where (upperid = 10000 and lowerid in (1, 2)) or (upperid = 20000 and lowerid = 1);
I got error: missing EOF at ')'.
Please help point to effective way to do multiget for composite row key in CQL3.
Thanks,
William
CQL does not yet support a logical "or" in select statements.
Instead, in your application your could combine the result sets from the two queries:
select * from mytable where upperid = 10000 and lowerid in (1, 2);
select * from mytable where upperid = 20000 and lowerid = 1;
Reference:
SO question: Alternative for OR condition after where clause in select statement Cassandra
Latest CQL docs

Resources