Perform anti INNER JOIN on two tables - ms-access

I was wondering if there is a quick way to do the following. As I understand it, an INNER JOIN on a field present in two tables returns information from the two tables having the field and its values in common. However, what I'm trying to do is to return the table rows that do not meet the INNER JOIN criteria. So, for example if I had Table 1 as
Product Price
Greens $2
Beans $1
Potatoes $3
Tomatoes $4
and table 2 as
Product Quantity
Potatoes 45
Tomatoes 100
Chickens 27
Turkeys 33
what I'm looking to output is
Product Price Quantity
Greens $2 NULL
Beans $1 NULL
Chickens NULL 27
Turkeys NULL 33
Is this at all possible?
Thanks!

You'd have to use two outer joins, one for products not having a corresponding price (price IS NULL) and one for products not having a corresponding quantity.
I used two separate queries (one for each join).
Next, used UNION to combine the results.
SELECT table1.Product, table1.Price, table2.Quantity
FROM table1
LEFT JOIN table2 ON table1.Product = table2.Product
WHERE table2.Quantity IS NULL
ORDER BY table1.Price DESC
UNION
SELECT table2.Product, table1.Price, table2.Quantity
FROM table1 RIGHT JOIN table2 ON table1.Product = table2.Product
WHERE table1.Price IS NULL
ORDER BY table2.Quantity

You can use NOT EXISTS for each of the tables and combine the results with UNION ALL:
select t1.product, t1.price, null as quantity from table1 as t1
where not exists (select 1 from table2 where product = t1.product)
union all
select t2.product, null as price, t2.quantity from table2 as t2
where not exists (select 1 from table1 where product = t2.product)

You can achieve it using the UNION and MINUS operations.
(SELECT * FROM t1 UNION SELECT * FROM t2) MINUS SELECT * FROM t1 INNER JOIN t2 ON t1.Product = t2.Product

Related

Use selected column in first query with IN clause in second query

Problem has been recreated below:
/* query - 1 */
Select id, title from table1;
/* returns */
id | title
-----------
1 | data-1
2 | data-2
3 | data-3
4 | data-4
5 | data-5
I want use this column id's data with IN clause in second query along with join.
Something like this:
Select id, title from table1
JOIN
Select anotherColumn from table2 where table2.id IN (1,2,3,4,5) on table1.id = table2.id
Instead of manually writing 1,2,3,4,5, how can I use the column data selected from first query in second query?
EDIT:
Actual query :
SELECT *
FROM
(
SELECT R.id, U.ic_id as rider, U.name, DP.department_name, R.location,
(R.distance - 1) + 10 as cost , R.timestamp, R.status
FROM requests AS R, iconnect.users AS U, iconnect.departments AS DP
WHERE R.pool = '125' AND R.rider = U.ic_id AND U.department = DP.id
) requestDetails
JOIN
(
SELECT AVG(rider_rating) AS rider_rating,rider
FROM
(
SELECT rider_rating, R.rider
FROM journeys AS J, requests AS R
WHERE J.req_id = R.id AND R.rider IN (12,13) LIMIT 999999
) AS allRatings
GROUP BY rider
) ratingsTable
ON requestDetails.rider = ratingsTable.rider
/* instead of (12,13) I want to use requestDetails.rider selected from the first derived table */
One option would be to use an EXISTS clause:
SELECT id, title
FROM table1 t1
WHERE EXISTS (SELECT 1 FROM table2 t2 WHERE t1.id = t2.id);
Actually, a plain inner join between the two tables would also work. But, you might want to use SELECT DISTINCT in case a given record in table1 could match more than one record in table2. That would leave us with this:
SELECT DISTINCT t1.id, t1.title
FROM table1 t1
INNER JOIN table2 t2
ON t1.id = t2.id;

need help on join query condtion

I am not much in db queries and I require some help on following .
I have two table structures as follow as
table1 :
Name Id1 Id2
Jack 1 1
Jack 1 1
Jack 1 1
table2 :
Name Id1 Id2
Jack 1 1
I used basic join query :
select *
from table1 tb1
join table2 tb2 on tb1.id1 = tb2.id1
and tb2.id2 = tb2.id2
output I get :
Jack 1 1
Jack 1 1
Jack 1 1
But I required following output:
Jack 1 1
Note: I like to show what records is available in table 2 when it combined together!!.. I would like to fetch data with respect table2 only
Thanks in advance.
Please try the following (does not uses aliases) ...
SELECT table2.Name,
table2.Id1,
table2.Id2
FROM table1
JOIN table2 ON table1.id1 = table2.id1 AND
table1.id2 = table2.id2
GROUP BY table2.id1,
table2.id2;
Or try the following (does use aliases)...
SELECT tb2.Name,
tb2.Id1,
tb2.Id2
FROM table1 tb1
JOIN table2 tb2 ON tb1.id1 = tb2.id1 AND
tb1.id2 = tb2.id2
GROUP BY tb2.id1,
tb2.id2;
By performing an INNER JOIN on table2 with table1 on those key fields you are limiting the output to only those rows from table1 that match Id1 and Id2 in table2 (Note : Where JOIN is not preceded by a JOIN type an INNER JOIN is performed). Since multiple rows in table1 meet this criteria you can limit your results to just one row for each matching set of criteria using GROUP BY
This should change the supplied actual query to...
SELECT delta.input_name,
delta.mtcn,
delta.at‌​tempt_id
FROM compliance.rtra_transactions rtra_txn
JOIN compliance.GNR_TEST_RUNS delta ON rtra_txn.mtcn_nr = delta.mtcn
AND rtra_txn.attemptid = delta.attempt_id
WHERE rtra_txn.year = 2017
AND rtra_txn.month = 2
AND rtra_txn.day = 17
AND rtra_txn.trns_ts BETWEEN '2017-02-17 00:00:00' AND '2017-02-17 23:59:00'
AND delta.MATCH_OUTCOME = 'MATCH'
AND delta.job_name = 'Feb17_Run_1'
AND rtra_txn.txn_map[ 'TRANSACTIONTYPE' ] IN ( '10', '7' )
GROUP BY delta.mtcn,
delta.attempt_id;
If you have any questions or comments, then please feel free to post a Comment accordingly.
Following query should work :
SELECT * FROM TBL2 T2
UNION
SELECT * FROM TBL1 T1;
You need to use LEFT JOIN as you mentioned in Biswabid answer comment I like to show what records is available in table 2 alone
select DISTINCT tb2.*
from table2 tb2
left join table1 tb1 on tb1.id1 = tb2.id1
and tb1.id2 = tb2.id2
WHERE tb1.id1 IS NULL

Joining 2 tables and adding price to give total revenue in MySQL

probably a simple query for someone to answer but I'm new at this and a bit stuck!
Trying to map from one table to another and sum together numbers in a column from Table 1. For example:
Table 1:
Item_ID Price
I0001 3.50
I0002 2.50
Table 2:
Item_ID Date_sold
I0001 10/11/14
I0002 12/11/14
What I want to do is tell MySQL that where 'Date_sold' is 'not null' in Table 2, to identify 'Item_id', match this back to table 1, read the 'Price' column in that row, and then add the results together for total revenue.
Any help appreciated!
I ll try something like that :
SELECT t1.Item_ID, SUM(Price) AS Total
FROM Table1 t1
INNER JOIN Table 2 t2
ON t1.Item_ID = t2.Item_ID
WHERE t2.Sold_date IS NOT NULL
GROUP BY Item_ID;
You will get the grand total by item if you add the group by statement.
If you only want the grand total :
SELECT SUM(Price) AS GrandTotal
FROM Table1 t1
INNER JOIN Table 2 t2
ON t1.Item_ID = t2.Item_ID
WHERE t2.Sold_date IS NOT NULL;
You could join both tales on the item_id, and then group by to sum the price:
SELECT date_sold, SUM(price)
FROM table_2
JOIN table_1 on table_2.item_id = table_1.item_id
WHERE date_sold IS NOT NULL
GROUP BY date_sold
select sum(table1.price) as revenue from table1 join table2 on table1.item_id=table2.item_id where table2.data_sold is not null

MySQL query to calculate percentage of total column

How to convert this result:
Group | Sum
Services | 11120.99
Vendas | 3738.00
Into:
Group | Sum
Services | 74.84
Vendas | 25.16
That is, the second displays the results as percentages of total.
This is what I tried:
SELECT categories.cat AS 'Group', SUM(atual) AS 'Sum'
FROM `table1` INNER JOIN
categories
ON table1.category_id=categories.id
GROUP BY categoria
you can left join a total sum that is not grouped or split up, and divide that by your sum query. this way you are just doing the total select once for faster runtime
SELECT cat, sum_atual, sum_atual/total_atual as percent_atual
FROM
( SELECT categories.cat AS cat, SUM(atual) AS sum_atual
FROM `table1`
JOIN categories ON table1.category_id=categories.id
GROUP BY categoria
) t
LEFT JOIN
( SELECT SUM(atual) as total_atual
FROM `table1`
) t1
SELECT categories.cat AS categoria,
SUM(atual) * 100 / (select sum(atual) from table1) AS percentages
FROM `table1`
INNER JOIN categories ON table1.category_id=categories.id
GROUP BY categoria
You can do this several ways. One is to just use a subquery in the select clause. As written below, this assumes that the category_id column in table1 always matches categories:
SELECT c.categoria AS "Group", SUM(t1.atual) AS "Sum",
SUM(t1.atual) / (SELECT SUM(t1.atual) FROM table1) as "Percent"
FROM `table1` t1 INNER JOIN
categories c
ON t1.category_id = c.id
GROUP BY c.categoria;
I changed the group by clause as well. It is a good idea for the group by and select to use the same columns. And I added table aliases to all the column references, another good practice.

Mysql union/join help with multiple columns

At first I thought this may work as a join but I'm not sure if this is really a union command or if even possible. Below is an example of the two tables and each has about 20 more columns of various different data.
Table 1
> id assembly user1 user2 containerID productID packageID
1 line2 Billy John 3794 4892 4589
2 line4 John Doug 7794 6201 7864
Table 2
> item_id name width height weight flag1 flag2
3794 Box 10 10 10 0 1
4892 Lamp 4 6 2 1 1
7864 BigBox 200 200 300 4 5
What I am trying to do is show all of Table 1 but replace the containerID, productID, and packageID with their name from Table 2 using the matching item_id. Tried doing this outside of mysql with foreach but with Table 2 having 30k rows it lags up "just a bit" when trying to display the hundreds of rows from Table 1 and replacing each id with its name equivalent.
To see all the table_1 records, use:
SELECT t1.id, t1.assembly, t1.user1, t1.user2,
t2c.name, t2pr.name, t2pk.name
FROM TABLE_1 t1
LEFT JOIN TABLE_2 t2c ON t2c.item_id = t1.containerid
LEFT JOIN TABLE_2 t2pr ON t2pr.item_id = t1.productid
LEFT JOIN TABLE_2 t2pk ON t2pk.item_id = t1.packageid
You can change those to INNER JOINs, but any row that doesn't match all three will not be in the resultset.
My query uses table aliases, because you have to join to the appropriate TABLE_2 column for each name you want to look up.
try to use something like this:
SELECT id, assembly, user1, user2,
(SELECT name from table2 where item_id = table1.containerID),
(SELECT name from table2 where item_id = table1.productID),
(SELECT name from table2 where item_id = table1.packageID)
FROM table1
ORDER BY id;
You'll need to join each row three times for each item_id
SELECT t1.*, t21.name,t22.name,t23.name FROM table_1 t1
INNER JOIN table_2 t21 ON t1.containerID = t21.itemid
INNER JOIN table_2 t22 ON t1.productId = t22.itemid
INNER JOIN table_2 t23 ON t1.packageID = t23.itemid
Make sure there's an index on table_2's itemid