Two tables join by number interval - sql

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 |
+------+----------+-------+--------+

Related

Access Multiple SQL Connection

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.

Transposing Data SQL

The data looks similar to this:
+----+------+-----------+-------+---------+---------+--------+
| ID | Unit | Floorplan | Sq Ft | Name | Amenity | Charge |
+----+------+-----------+-------+---------+---------+--------+
| 1 | 110 | A1 | 750 | Alan | GARAGE | 50 |
| 2 | | | | | RENT | 850 |
| 3 | | | | | PEST | 2 |
| 4 | | | | | TRASH | 15 |
| 5 | | | | | TOTAL | 20 |
| 6 | 111 | A2 | 760 | Bill | STORAGE | 35 |
| 7 | | | | | GARAGE | 50 |
| 8 | | | | | RENT | 850 |
| 9 | | | | | PEST | 2 |
| 10 | | | | | TOTAL | 15 |
| 11 | 112 | A3 | 770 | Charlie | PETRENT | 20 |
| 12 | | | | | STORAGE | 35 |
| 13 | | | | | GARAGE | 50 |
| 14 | | | | | RENT | 850 |
| 15 | | | | | TOTAL | 2 |
+----+------+-----------+-------+---------+---------+--------+
I am new to SQL and trying my best using Microsoft Access, but I need help.
The data needs to look like this:
My first step is to separate the units from the rest with
SELECT * FROM table WHERE Unit <> NULL;
and after that I've usually just hard-input the rest.
My idea was as follows:
INSERT INTO table
VALUES (NULL,NULL,...,'Pest',$2)
FROM table
WHERE NOT EXIST 'Pest' BETWEEN x AND y
/* where x = Total 1 and y = Total 2*/
Am I on the right track? I probably need a loop or a join, but I'm not at that level yet.
You can use a crosstab query, though a bit convoluted it is:
TRANSFORM
Sum(TableUnit.Charge) AS SumOfCharge
SELECT
S.Unit,
S.Floorplan,
S.SqFt,
S.Name,
S.Amenity
FROM
TableUnit,
(SELECT
Q.Id,
Val(DMax("Id","TableUnit","Id<=" & Q.[Id] & " And Unit Is Not Null")) AS ParentId
FROM TableUnit As Q) AS T,
(SELECT
TableUnit.Id,
TableUnit.Unit,
TableUnit.Floorplan,
TableUnit.SqFt,
TableUnit.Name,
TableUnit.Amenity
FROM
TableUnit
WHERE
TableUnit.Unit Is Not Null) AS S
WHERE
TableUnit.Id=[T].[Id]
AND
T.ParentId)=[S].[Id]
GROUP BY
T.ParentId,
S.Unit,
S.Floorplan,
S.SqFt,
S.Name,
S.Amenity
PIVOT
TableUnit.Amenity In
("Garage","Pest","Trash","PetRent","Storage","Rent");
Your test data differs a little from your expected output, so:
My MSAccess is rather rusty, but something like this should work:
SELECT t0.Unit, t0.Floorplan, t0.[Sq Ft], t0.Name, t0.Amenity
, SUM(IIF(tM.Amenity = 'GARAGE', Charge, 0)) AS [Garage]
, SUM(IIF(tM.Amenity = 'PEST', Charge, 0)) AS [Pest]
FROM (
SELECT t1.id AS id0, MIN(t2.id) AS idN
FROM t AS t1
INNER JOIN t AS t2 ON t1.id < t2.id
WHERE t1.Unit <> '' AND t2.Unit <> ''
) AS groups
INNER JOIN t AS t0 ON t0.id = groups.id0
LEFT JOIN t AS tM ON tM.id > groups.id0 AND tm.id < groups.idN
GROUP BY t0.Unit, t0.Floorplan, t0.[Sq Ft], t0.Name, t0.Amenity
;
Though, if I remember correctly, and it hasn't changed in newer versions; you can't have true subqueries and will need to make groups a separate query you can join to as if it were a table/view.

select from table using sql query

Table
id | name | type | x | y | z | refer
-----+------------+---------------+---------------+-------------+------------------+-----------------
1001 | A | 4 | | | | 0
2000 | B | 2 | -1062731776 | | -65536 | 1001
2001 | C | 2 | 167772160 | | -16777216 | 1001
2002 | D | 2 | -1408237568 | | -1048576 | 1001
I need to select columns name,x,y,z if in refer column it refers to id column
and name must be of that id's name. Is it possible with a single query? can anyone please help
here, output should be:
name| x | y | z
----+-----------------+-------------+-----------------
A | -1062731776 | | -65536
A | 167772160 | | -16777216
A | -1408237568 | | -1048576
SELECT t1.name, t2.x, t2.y, t2.z FROM TABLENAME t1
JOIN TABLENAME t2 on t1.id = t2.refer

Joining two tables and calculating divide-SUM from the resulting table in SQL Server

I have one table that looks like this:
+---------------+---------------+-----------+-------+------+
| id_instrument | id_data_label | Date | Value | Note |
+---------------+---------------+-----------+-------+------+
| 1 | 57 | 1.10.2010 | 200 | NULL |
| 1 | 57 | 2.10.2010 | 190 | NULL |
| 1 | 57 | 3.10.2010 | 202 | NULL |
| | | | | |
+---------------+---------------+-----------+-------+------+
And the other that looks like this:
+----------------+---------------+---------------+--------------+-------+-----------+------+
| id_fundamental | id_instrument | id_data_label | quarter_code | value | AnnDate | Note |
+----------------+---------------+---------------+--------------+-------+-----------+------+
| 1 | 1 | 20 | 20101 | 3 | 28.2.2010 | NULL |
| 2 | 1 | 20 | 20102 | 4 | 1.8.2010 | NULL |
| 3 | 1 | 20 | 20103 | 5 | 2.11.2010 | NULL |
| | | | | | | |
+----------------+---------------+---------------+--------------+-------+-----------+------+
What I would like to do is to merge/join these two tables in one in a way that I get something like this:
+------------+--------------+--------------+----------+--------------+
| Date | Table1.Value | Table2.Value | AnnDate | quarter_code |
+------------+--------------+--------------+----------+--------------+
| 1.10.2010. | 200 | 3 | 1.8.2010 | 20102 |
| 2.10.2010. | 190 | 3 | 1.8.2010 | 20102 |
| 3.10.2010. | 202 | 3 | 1.8.2010 | 20102 |
| | | | | |
+------------+--------------+--------------+----------+--------------+
So the idea is to order them by Date from Table1 and since Table2 Values only change on the change of AnnDate we populate the Resulting table with same values from Table2.
After that I would like to go through the resulting table and create another (Final table) with the following.
On Date 1.10.2010. take last 4 AnnDates (so it would be 1.8.2010. and f.e. 20.3.2010. 30.1.2010. 15.11.2009) and Table2 values on those AnnDate. Make SUM of those 4 values and then divide the Table1 Value with that SUM.
So we would get something like:
+-----------+---------------------------------------------------------------+
| Date | FinalValue |
+-----------+---------------------------------------------------------------+
| 1.10.2010 | 200/(Table2.Value on 1.8.2010+Table2.Value on 20.3.2010 +...) |
| | |
+-----------+---------------------------------------------------------------+
Is there any way this can be done?
EDIT:
Hmm yes now I see that I really didn't do a good job explaining it.
What I wanted to say is
I try INNER JOIN like this:
SELECT TableOne.Date, TableOne.Value, TableTwo.Value, TableTwo.AnnDate, TableTwo.quarter_code
FROM TableOne
INNER JOIN TableTwo ON TableOne.id_intrument=TableTwo.id_instrument WHERE TableOne.id_data_label = somevalue AND TableTwo.id_data_label = somevalue AND date > xxx AND date < yyy
And this inner join returns 2620*40 rows which means for every AnnDate from table2 it returns all Date from table1.
What I want is to return 2620 values with Dates from Table1
Values from table1 on that date and Values from table2 that respond to that period of dates
f.e.
Table1:
+-------+-------+
| Date | Value |
+-------+-------+
| 1 | a |
| 2 | b |
| 3 | c |
| 4 | d |
+-------+-------+
Table2
+-------+---------+
| Value | AnnDate |
+-------+---------+
| x | 1 |
| y | 4 |
+-------+---------+
Resulting table:
+-------+---------+---------+
| Date | ValueT1 | ValueT2 |
+-------+---------+---------+
| 1 | a | x |
| 2 | b | x |
| 3 | c | x |
| 4 | d | y |
+-------+---------+---------+
You need a JOIN statement for your first query. Try:
SELECT TableOne.Date, TableOne.Value, TableTwo.Value, TableTwo.AnnDate, TableTwo.quarter_code FROM TableOne
INNER JOIN TableTwo
ON TableOne.id_intrument=TableTwo.id_instrument;

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.