sqlite join 2 tables with same columns - sqlite

I'm trying to get a result from two sqlite tables that contain the same columns but have no other relation. Both have the date and amount columns and all I want is a new table as a result to show dates and amounts from both tables.
Table A
+----------+-------+
| date | amount|
+----------+-------+
|10-01-2013| 3.8 |
|12-23-2104| 4.2 |
+----------+-------+
and
Table B
+----------+-------+
| date | amount|
+----------+-------+
|10-03-2013| 2.4 |
|12-28-2014| 3.5 |
+----------+-------+
And the desired table would be
+----------+----------+---------+
| date | A.amount | B.amount|
+----------+----------+---------+
|10-01-2013| 3.8 | NULL |
|10-03-2013| NULL | 2.4 |
|12-23-2104| 4.2 | NULL |
|12-28-2014| NULL | 3.5 |
+----------+----------+---------+
I tried many posts in the forum but I couldn't find any that match my need.
Could you help?

What you need is not a JOIN is a UNION.
see:
UNIONS in SQLITE
Something like:
SELECT Date, Amount as Amount1, NULL AS Amount2
FROM TableA
UNION ALL
SELECT Date, NULL AS Amount1, Amount as Amount2
FROM TableB

Related

global or local indexes on column with duplicate value in Oracle 19C?

I have below table on Oracle19c(I am an oracle newbie). 4 million rows are inserted into the table daily and for now this table have 40 column and 240 million rows.
I usually search the table with user_id and MyTimestamp columns filter query and it takes 10 minutes to return the answer.
Example:
select * from table where user_id=123581 and MyTimestamp between 1657640396 and 1657777396
Note: Duplicate values are stored in the user_id and MyTimestamp columns.
I want partition monthly on MyTimestamp and index on user_id but which global or local indexes is suitable for indexing and how do I do it?
----------------------------------------------------------------------------------------------------
| id | MyTimestamp | Name | user_id ...
----------------------------------------------------------------------------------------------------
| 0 | 1657640396 | John | 123581 ...
| 1 | 1657638832 | Tom | 168525 ...
| 2 | 1657640265 | Tom | 168525 ...
| 3 | 1657640292 | John | 123581 ...
| 4 | 1657640005 | Jack | 896545 ...
--------------------------------------------------------------------------------------------------
If the majority of your queries contain the partition key, then better create LOCAL indexes:
CREATE INDEX index_name ON table_name (MyTimestamp, user_id) LOCAL;
Local indexes are smaller (i.e. the index partition) and thus faster and you don't have to rebuild the index when you drop an outdated partition.

How can I set multiple aliases for a single derived table in MariaDB 5.5?

Consider a database with three tables:
goods (Id is the primary key)
+----+-------+-----+
| Id | Name | SKU |
+----+-------+-----+
| 1 | Nails | 123 |
| 2 | Nuts | 456 |
| 3 | Bolts | 789 |
+----+-------+-----+
invoiceheader (Id is the primary key)
+----+--------------+-----------+---------+
| Id | Date | Warehouse | BuyerId |
+----+--------------+-----------+---------+
| 1 | '2021-10-15' | 1 | 223 |
| 2 | '2021-09-18' | 1 | 356 |
| 3 | '2021-07-13' | 2 | 1 |
+----+--------------+-----------+---------+
invoiceitems (Id is the primary key)
+----+----------+--------+-----+-------+
| Id | HeaderId | GoodId | Qty | Price |
+----+----------+--------+-----+-------+
| 1 | 1 | 1 | 15 | 1.1 |
| 2 | 1 | 3 | 7 | 1.5 |
| 3 | 2 | 1 | 12 | 1.5 |
| 4 | 3 | 3 | 3 | 1.3 |
+----+----------+--------+-----+-------+
What I'm trying to do is to get the MAX(invoiceheader.Date) for every invoiceitems.GoodId. Or, in everyday terms, to find out, preferably in a single query, when was the last time any of the goods were sold, from a specific warehouse.
To do that, I'm using a derived query, and the solution proposed here . In order to be able to do that, I think that I need to have a way of giving multiple (well, two) aliases for a derived table.
My query looks like this at the moment:
SELECT tmp.* /* placing the second alias here, before or after tmp.* doesn't work */
FROM ( /* placing the second alias, tmpClone, here also doesn't work */
SELECT
invoiceheader.Id,
invoiceheader.Date,
invoiceitems.HeaderId,
invoiceitems.Id,
invoiceitems.GoodId
FROM invoiceheader
LEFT JOIN invoiceitems
ON invoiceheader.Id = invoiceitems.HeaderId
WHERE invoiceheader.Warehouse = 3
AND invoiceheader.Date > '0000-00-00 00:00:00'
AND invoiceheader.Date IS NOT NULL
AND invoiceheader.Date > ''
AND invoiceitems.GoodId > 0
ORDER BY
invoiceitems.GoodId ASC,
invoiceheader.Date DESC
) tmp, tmpClone /* this doesn't work with or without a comma */
INNER JOIN (
SELECT
invoiceheader.Id,
MAX(invoiceheader.Date) AS maxDate
FROM tmpClone
WHERE invoiceheader.Warehouse = 3
GROUP BY invoiceitems.GoodId
) headerGroup
ON tmp.Id = headerGroup.Id
AND tmp.Date = headerGroup.maxDate
AND tmp.HeaderId = headerGroup.Id
Is it possible to set multiple aliases for a single derived table? If it is, how should I do it?
I'm using 5.5.52-MariaDB.
you can use both (inner select) and left join to achieve this for example:
select t1.b,(select t2.b from table2 as t2 where t1.x=t2.x) as 'Y' from table as t1 Where t1.y=(select t3.y from table3 as t3 where t2.a=t3.a)
While this doesn't answer my original question, it does solve the problem from which the question arose, and I'll leave it here in case anyone ever comes across a similar issue.
The following query does what I'd intended to do - find the newest sale date for the goods from the specific warehouse.
SELECT
invoiceheader.Id,
invoiceheader.Date,
invoiceitems.HeaderId,
invoiceitems.Id,
invoiceitems.GoodId
FROM invoiceheader
INNER JOIN invoiceitems
ON invoiceheader.Id = invoiceitems.HeaderId
INNER JOIN (
SELECT
MAX(invoiceheader.Date) AS maxDate,
invoiceitems.GoodId
FROM invoiceheader
INNER JOIN invoiceitems
ON invoiceheader.Id = invoiceitems.HeaderId
WHERE invoiceheader.Warehouse = 3
AND invoiceheader.Date > '0000-00-00 00:00:00'
AND invoiceheader.Date IS NOT NULL
AND invoiceheader.Date > ''
GROUP BY invoiceitems.GoodId
) tmpDate
ON invoiceheader.Date = tmpDate.maxDate
AND invoiceitems.GoodId = tmpDate.GoodId
WHERE invoiceheader.Warehouse = 3
AND invoiceitems.GoodId > 0
ORDER BY
invoiceitems.GoodId ASC,
invoiceheader.Date DESC
The trick was to join by taking into consideration two things - MAX(invoiceheader.Date) and invoiceitems.GoodId - since one GoodId can only appear once inside a specific invoiceheader / invoiceitems JOINing (strict limit imposed on the part of the code which inserts into invoiceitems).
Whether this is the most optimal solution (ignoring the redundant conditions in the query), and whether it would scale well, remains to be seen - it has been tested on tables with ~5000 entries for invoiceheader, ~60000 entries for invoiceitems, and ~4000 entries for goods. Execution time was < 1 sec.

union multiple tables and group with aggregation (SQlite)

I have such kind of a data:
table1
id | part | price
1 | ox900 | 100
2 | ox980 | 200
and
table2
id | part | price
1 | ox560 | 560
2 | ox980 | 120
as result I want to get such schema:
id | part | priceTable1 | priceTable2 | minPrice
1 | ox900 | 100 | | 100
1 | ox980 | 200 | 120 | 120
1 | ox560 | | 560 | 560
to simplify it can be without minPrice column...
now I have such query:
SELECT *
FROM (select part, price from supportContacts
union all
select part, price from supportContacts2)
group by part
but it's not exactly what I want to achieve.
Is it possible somehow to do, what I've described above?
Also a fiddle: http://sqlfiddle.com/#!7/f7401/7/0
SQLite does not support full outer joins, so get a list of all parts first, and then look up their prices with left outer joins:
SELECT part,
table1.price AS priceTable1,
table2.price AS priceTable2,
min(ifnull(table1.price, 'inf'),
ifnull(table2.price, 'inf')) AS minPrice
FROM (SELECT part FROM table1
UNION
SELECT part FROM table2)
LEFT JOIN table1 USING (part)
LEFT JOIN table2 USING (part);
(fiddle)

Join a query result set with an existing table in sqlite?

I have a query result set like this:
value | id
500 | 1
400 | 1
300 | 2
and a product table:
product_name | id
product_1 | 1
product_2 | 2
product_5 | 3
product_6 | 4
product_9 | 5
product_0 | 6
Now I want to find the product_name from product table for every row in query result set and join the result to look like following:
The result after joining should be following:
product_name | id | value
product_1 | 1 | 500
product_1 | 1 | 400
product_2 | 2 | 300
I am getting confused how to use left join to achieve the result.
You'd join based on the value that's common between the two tables; in this case, it's id.
It doesn't seem like you want any NULL values for value, so you wouldn't use a LEFT JOIN; you'd want an INNER JOIN instead.
This would get you pretty much what you want; bear in mind that this is untested.
SELECT p.product_name, qr.id, value
FROM product p
INNER JOIN query_result_set qr ON qr.id = p.id
ORDER BY value DESC;
Also, your expectations are wrong - product_5 has an id of 3, so it wouldn't appear in this join result.

sqlite extract two row from two tables to create a new table

I have an sqlite db with two table
table1
------------------------------
TIME | ElevationA| ElevationB|
-----|-----------|-----------|
T1 | eA1 | eB1  |
T2 | eA2 | eB2 |
table2
------------------------------
TIME | Temperat A| Temperat B|
-----|-----------|-----------|
T1 | tA1 | tB1  |
T2 | tA2 | tB2 |
I am searching for a "magic" command that make a table of all parameter at a given time, e.g something that would be like:
SELECT WHERE TIME=T1 table1 AS ELEV ,table2 AS TEMP
and that would result in
table3
------------
ELEV | TEMP |
-----|----- |
eA1 | tA1 |
eB1 | tB1 |
Of course I could bash script it but I would prefer a to create a view in SQLite as it is more straightforwards and avoid to duplicate the data.
Any idea welcome
You can use:
CREATE TABLE TABLE3(ELEV,TEMP);
INSERT INTO TABLE3(ELEV,TEMP) VALUES((SELECT TIME FROM TABLE1 WHERE TIME = T1),SELECT TIME FROM TABLE2 WHERE TIME =T2));
These 2 select clauses must return the same number of records.

Resources