Access Multiple SQL Connection - sql

I have two queries in Access which are returning two tables like:
(The tables have both about 1000 lines)
SELECT
(select count(*)
from Table1 T2
where T1.Name=T2.Name and T1.Variable1 >= T2.Variable1) as Rank,
T1.Name,
T1.Variable1
FROM Table1 T1
Results:
+-------+---------+------------+
| Rank | Name | Variable1 |
+-------+---------+------------+
| 1 | Tim | x |
| 2 | Tim | y |
| 3 | Tim | z |
| 1 | Susan | x |
| 2 | Susan | w |
+-------+---------+------------+
Second query:
SELECT (select count(*)
from Table2 T2
where T1.Name=T2.Name and T1.Variable2 >= T2.Variable2) as Rank,
T1.Name,T1.Variable2
FROM Table2 T1
Results:
+--------+---------+------------+
| Ran | Name | Variable2 |
+--------+---------+------------+
| 1 | Tim | a |
| 2 | Tim | b |
| 3 | Tim | c |
| 1 | Susan | a |
| 2 | Susan | c |
+--------+---------+------------+
I want to link them:
Select distinct Table1.Name, Table1.Variable1, Table2.Variable2
from Table1, Table2
where Table1.Name=Table2.Name and Table1.Rank=Table2.Rank
Results:
+-----------+---------+-------------+------------+
| Rank | Name | Variable1 | Variable2 |
+-----------+---------+-------------+------------+
| 1 | Tim | x | a |
| 2 | Tim | y | b |
| 3 | Tim | z | c |
| 1 | Susan | x | a |
| 2 | Susan | w | b |
+-----------+---------+-------------+------------+
But that link isn't performing well in access.
I also tried to link them via "join" but the performance isnt getting better.

These ranking queries are expensive (the subquery has to be executed for each row of the main table).
Stacking / cascading expensive queries in Access often performs badly.
Your best option is to change your 1st and 2nd query into "Create table" (SELECT INTO) queries, storing the results in intermediate tables.
E.g.
SELECT
(select count(*)
from Table1 T2
where T1.Name=T2.Name and T1.Variable1 >= T2.Variable1) as Rank,
T1.Name,
T1.Variable1
INTO Result1
FROM Table1 T1
Then use these tables (Result1, Result2) as input for the JOIN.

Related

How to join a grouped table in sql?

Novice in SQL here but hopefully someone can help. I have two tables. For the simplicity here is how the tables are structured.
Table 1:
+------------+-------+-----------+------------+
| department | sales | date | sales_code |
+------------+-------+-----------+------------+
| 1 | 50 | 5/26/2021 | A |
+------------+-------+-----------+------------+
| 2 | 150 | 5/26/2021 | B |
+------------+-------+-----------+------------+
| 1 | 200 | 5/25/2021 | C |
+------------+-------+-----------+------------+
| 2 | 250 | 5/24/2021 | D |
+------------+-------+-----------+------------+
Table 2:
+------+------------+-------+-----------+-----------------------+
| item | department | sales | date | column I want to join |
+------+------------+-------+-----------+-----------------------+
| 31 | 1 | 50 | 5/26/2021 | x |
+------+------------+-------+-----------+-----------------------+
| 30 | 2 | 150 | 5/26/2021 | x |
+------+------------+-------+-----------+-----------------------+
| 29 | 1 | 200 | 5/25/2021 | x |
+------+------------+-------+-----------+-----------------------+
| 28 | 2 | 250 | 5/24/2021 | x |
+------+------------+-------+-----------+-----------------------+
I need to join table 2 to table 1 - however it needs to be aggregated by department sales first, this is because table 2 is already aggregated by department sales. Here is what I was thinking but cannot seem to get it to work.
SELECT t1.*, t2.*
FROM table1 as t1
JOIN (
SELECT department, date, column_i_want, sum(sales)
FROM table2
GROUP BY department ) as t2
ON t2.department = t1.department AND t1.date = t2.date
Desired Output:
+------------+-------+-----------+------------+-----------------------+
| department | sales | date | sales_code | column I want to join |
+------------+-------+-----------+------------+-----------------------+
| 1 | 50 | 5/26/2021 | A | x |
+------------+-------+-----------+------------+-----------------------+
| 2 | 150 | 5/26/2021 | B | x |
+------------+-------+-----------+------------+-----------------------+
| 1 | 200 | 5/25/2021 | C | x |
+------------+-------+-----------+------------+-----------------------+
| 2 | 250 | 5/24/2021 | D | x |
+------------+-------+-----------+------------+-----------------------+
Any help would be appreciated.
There are several ways to go about doing that, the easiest one is to create a view
CREATE VIEW t2 AS
SELECT department, date, column_i_want, sum(sales)
FROM table2
GROUP BY department;
then it's easier to join them (you can also use a With clause instead of a view but it can get messy)
SELECT *
FROM table1 NATURAL JOIN t2
here is what you want:
select t2.*, t1.sales_code
from table2 t2
join table1 t1
on t1.department = t2.department
and t1.date = t2.date

Is it faster to do WHERE IN or INNER JOIN in Redshift

I have 2 tables in redshift:
table1
| ids |
|------:|
| 1 |
| 2 |
| 6 |
| 9 |
| 12 |
table2
| id | value |
|-----:|---------:|
| 1 | 0.134435 |
| 2 | 0.767417 |
| 3 | 0.779567 |
| 4 | 0.726051 |
| 5 | 0.405138 |
| 6 | 0.775206 |
| 7 | 0.699945 |
| 8 | 0.499433 |
| 10 | 0.457386 |
| 9 | 0.227511 |
| 10 | 0.369292 |
| 11 | 0.653735 |
| 12 | 0.537251 |
| 2 | 0.953539 |
| 13 | 0.377625 |
| 14 | 0.973905 |
| 4 | 0.104643 |
| 1 | 0.450627 |
And I basically want to get the rows in table2 where id is in table1 and I have 2 possibilities:
SELECT *
FROM table2
WHERE id IN (SELECT ids FROM table1)
or
SELECT t2.id, t2.value
FROM table2 t2
INNER JOIN table1 t1
ON t2.id = t1.ids
I want to know if there is any performance difference between them.
(I know I could just test in this example to find out but I would like to know if there is one which is always faster)
Edit: table1.ids is a unique column
The two queries do different things.
The JOIN can multiply the number of rows if id is duplicated in table1.
The IN will never duplicate rows.
If id can be duplicated, you should use the version that does what you want. If id is guaranteed to be unique, then the two are functionally equivalent.
In my experience, JOIN is typically at least as fast a IN. Of course, you can test on your data, but that is a starting point.

Two tables join by number interval

Hello I have two SQL tables, first look like this:
| id | position | name |
|----|----------|-------|
| 1 | 553 | John |
| 2 | 876 | James |
| 3 | 999 | Jack |
And second like this:
| id | class | interval_start | interval_end |
|----|--------|----------------|--------------|
| 1 | class1 | 500 | 580 |
| 2 | class2 | 600 | 700 |
| 3 | class3 | 900 | 1200 |
And I would like to add class from second table to first table based on interval (if t1.position is bigger than start and smaller than end - add another column with class)
So result should be:
| id | position | name | class |
|----|----------|-------|--------|
| 1 | 553 | John | class1 |
| 2 | 876 | James | |
| 3 | 999 | Jack | class3 |
I am not sure how to do that, because I have very large tables (millions of rows). I can also download the data and process it manually in Python.
Which way do you think will be optimal for this task?
You can use left join:
select t1.*, t2.class
from table1 t1 left join
table2 t2
on t1.position between t2.interval_start and t2.interval_end;
You can try below SQL, it will fulfill your requirement.
select t1.id,
t1.position,
t1.name,
t2.class
from table1 t1
left join table2 t2
on (t1.id = t2.id
and t1.position between t2.interval_start and t2.interval_end
);
Output:
+------+----------+-------+--------+
| id | position | name | class |
+------+----------+-------+--------+
| 1 | 553 | John | class1 |
| 3 | 999 | Jack | class3 |
| 2 | 876 | James | NULL |
+------+----------+-------+--------+

Create a combined list from two tables

I have a table with CostCenter_ID (int) and a second table with Process_ID (int).
I'd like to combine the results of both tables so that each cost center ID is assigned to all process IDs, like so:
|CostCenterID | ProcessID |
---------------------------
| 1 | 1 |
| 1 | 2 |
| 1 | 3 |
| 2 | 1 |
| 2 | 2 |
| 2 | 3 |
| 3 | 1 |
| 3 | 2 |
| 3 | 3 |
I've done it before but I'm drawing a blank. I've tried this:
SELECT CostCenter_ID,NULL FROM dbo.Cost_Centers
UNION ALL
SELECT NULL,Process_ID FROM dbo.Processes
which returns this:
|CostCenterID | ProcessID |
---------------------------
| 1 | NULL |
| NULL | 1 |
| NULL | 2 |
| NULL | 3 |
Try:
select a.CostCenterID, b.ProcessID
from table1 a
cross join table2 b
or:
select a.CostCenterID, b.ProcessID
from table1 a
,table2 b
NB: cross join is the better method as it makes it clearer to the reader what your intentions are.
More info (with pics) here: http://www.w3resource.com/sql/joins/cross-join.php

Query for data in two tables connected by a third. Data Sometimes only on one

I thought I could figure this out but I am having a lot of issues.I have 3 Tables, Table1, Table2, and Table3. These tables where designed by someone else and I have to work with them. They were not designed to be used the way they are used today.
The bottom line is I need to be able to enter an Item_No, this will always exist in Table2. And if the Item_No can also be found in Table 3, could be multiple times or none, and there can be times where I can find it 5 times in Table2 and only 3 times in Table3. If it is in Table3 it will also be in Table1.
So, using the Item_No i can find on Table2, return the Order_qty's associated with those rows. Then using the if exist getting Table1.ID where Table1.ID = Table3.ID WHERE Table3.Item_No = Table2.Item_No
I came up with the following, it does not give me errors but simply stops code execution during a C# fill. I had it working for finding the Item_No on Table3 and returning what it finds, I have ONLY changed this line of code since so I KNOW this is the issue.
Here is what I could come up with that is not working:
SELECT Table1.ID,
Table2.Order_Qty As [Qty of Full Order], Table2.Item_No As [Set No]
FROM Table2
LEFT JOIN Table3
ON Table2.Item_No = Table3.Item_No
AND Table2.Order_No = Table3.Order_No
LEFT JOIN Table1
ON Table1.Order_No = Table2.Order_No
AND Table1.ID = Table3.ID
WHERE Table2.Item_No = #m_strUserEnteredSeachValue
ORDER BY Table2.Order_No DESC
*Example Data: *
Table 1
+----------+--------------+-------------------+
| Order_No | Sub_Order_No | Sub_Order_Contact |
+==========+==============+===================+
| 1 | 1 | John Doe |
+----------+--------------+-------------------+
| 1 | 2 | Jane Doe |
+----------+--------------+-------------------+
| 1 | 3 | Foo |
+----------+--------------+-------------------+
| 1 | 4 | Bar |
+----------+--------------+-------------------+
| 1 | 5 | Foo2 |
+----------+--------------+-------------------+
Table 2
+----------+--------------+-------------------+
| Order_No | Item_No | Customer_Item_Name|
+==========+==============+===================+
| 1 | 1 | 1234567890 |
+----------+--------------+-------------------+
| 1 | 2 | 1234567891 |
+----------+--------------+-------------------+
| 1 | 3 | 1234567892 |
+----------+--------------+-------------------+
| 1 | 4 | 1234567893 |
+----------+--------------+-------------------+
| 1 | 5 | 1234567894 |
+----------+--------------+-------------------+
| 1 | 6 | 1234567895 |
+----------+--------------+-------------------+
| 2 | 1 | 0987654321 |
+----------+--------------+-------------------+
| 2 | 2 | 0987654322 |
+----------+--------------+-------------------+
| 2 | 3 | 0987654323 |
+----------+--------------+-------------------+
| 3 | 1 | 1234567893 |
+----------+--------------+-------------------+
And Table 3
+----------+--------------+-------------------+--------------+
| Order_No | Item_No | Customer_Item_Name| Sub_Order_No |
+==========+==============+===================+==============+
| 1 | 1 | 1234567890 | 1 |
+----------+--------------+-------------------+--------------+
| 1 | 2 | 1234567891 | 2 |
+----------+--------------+-------------------+--------------+
| 1 | 3 | 1234567892 | 2 |
+----------+--------------+-------------------+--------------+
| 1 | 4 | 1234567893 | 3 |
+----------+--------------+-------------------+--------------+
| 1 | 5 | 1234567894 | 4 |
+----------+--------------+-------------------+--------------+
| 1 | 6 | 1234567895 | 4 |
+----------+--------------+-------------------+--------------+
| 1 | 4 | 1234567893 | 4 |
+----------+--------------+-------------------+--------------+
The Result I am looking for: If I search for Item 1234567893
+----------+--------------+-------------------+--------------+-------------------+
| Order_No | Item_No | Customer_Item_Name| Sub_Order_No | Sub_Order_Contact |
+==========+==============+===================+==============+===================+
| 3 | 1 | 1234567893 | | |
+----------+--------------+-------------------+--------------+-------------------+
| 1 | 4 | 1234567893 | 3 | Foo |
+----------+--------------+-------------------+--------------+-------------------+
| 1 | 4 | 1234567893 | 4 | Bar |
+----------+--------------+-------------------+--------------+-------------------+
A pragmatic answer to a problem like this is to split it into a couple of queries. Query Table #2 first, and then based on that result set, run additional queries into #1 or #3.
Another angle is to query on Table #2 and use subqueries to reach-out-there into Table #1 or Table #3 to fetch data you need.
Try this:
declare #m_strUserEnteredSeachValue varchar(10) = '1234567893';
with a as
(
select
Order_No, Item_No, Customer_Item_Name
from
Table2
UNION
select
Order_No, Item_No, Customer_Item_Name
from
Table3
)
select
a.Order_No,
a.Item_No,
a.Customer_Item_Name,
Table3.Sub_Order_No,
Table1.Sub_Order_Contact
from
a
left join
Table3
on
Table3.Order_No=a.Order_No
and Table3.Item_No=a.Item_No
and Table3.Customer_Item_Name=a.Customer_Item_Name
left join
Table1
on
Table1.Sub_Order_No = Table3.Sub_Order_No
where
#m_strUserEnteredSeachValue = a.Customer_Item_Name
order by
a.Item_No, Table3.Sub_Order_No
SqlFiddle demo: http://www.sqlfiddle.com/#!3/973d8/3
I have no idea if this is what you are trying to arrive at or not, since it's difficult to understand from you question. All I know that this query gives the dataset that you put in OP.