select timestamps within ranges - sql-server

I have got 2 tables. Example Table 1:
ID episode_id episode_start episode_end
----------------------------------------------------
1 1 1 2
1 2 4 5
1 3 96 105
1 4 110 114
2 1 1 4
2 2 13 24
Example Table 2
ID timestamp Other_info
--------------------------------
1 1 111
1 2 142
1 3 114
1 4 112
1 5 116
1 6 123
2 1 145
2 2 156
2 3 154
I would like to merge the two tables based upon table2.timestamp = between table1.episode_start and table1.episode_end.
The final table should be a subset of table 2 with only the timestamprows where there is an episode.
Question: How to do this? What is the most computational efficient way?
EDIT: In reallity my tables are much longer.
So, for example, the episode_start of ID = 1 be the same as the episode start of ID=1200 in episode 12. So simply merging them does not work.
EDIT: EXPECTED OUTPUT:
ID timestamp Other_info
--------------------------------
1 1 111
1 2 142
1 4 112
1 5 116
2 1 145
2 2 156
2 3 154
and so on. The merge is basically some sort of filter of table 2 by table 1.

select table2.id, timestamp, other_info
from table1
left join table2 on table2.timestamp between table1.episode_start and table1.episode_end
where table2.id = table1.id
Output:
id timestamp Other_info
---------------------------------------
1 1 111
1 2 142
1 4 112
1 5 116
2 1 145
2 2 156
2 3 154

Related

Get output of multiple Counts in one query

Could you help me how to write a query for the following issue:
There are two tables:
Table persons:
P_id Name BirthDate
1 N1 2016-08-02
2 N2 2015-05-02
3 N3 2013-06-01
4 N4 2014-01-09
Table visited:(p_id is foreign key to table persons)
Id. Visitor_id. P_id. Visit_date
1 10 1 2017-03-05
2 11 2 2017-01-01
3 10 2 2017-02-03
4 12 3 2016-05-07
5 11 4 2016-04-09
6 10 1 2017-04-09
We are going to get the count of visited by each Visitor and also count of visited distinct person on filter on for those person who their age are under 1, between 1 and 2, between 2 and 3 at date of visit_date by each visitor_id.
The results should be like :
Under_one Bet_one_two Bet_two_three
Visitor_id VisitedCount/PersonCount VisitedCount/PersonCount VisitedCount/PersonCount
10 2 1 1 1 0 0
11 0 0 1 1 1 1
12 0 0 0 0 1 1
Between 1 and 2 means the result of subtracting visited_date and birthdate (for example : the result of 2013/03/05 - 2011/06/07) is between 1 and 2 years.
I don't know if I can give you the output laid out exactly as you have specified, but this
SELECT
visited.Visitor_id,
visited.P_id,
Int(([Visit_date]-[BirthDate])/365) AS Age,
Count(persons.P_id) AS NumVisits
FROM persons INNER JOIN visited ON persons.P_id = visited.P_id
GROUP BY
visited.Visitor_id,
visited.P_id,
Int((-[BirthDate]+[Visit_date])/365);
returns
Visitor_id P_id Age NumVisits
10 1 0 2
10 2 1 1
11 2 1 1
11 4 2 1
12 3 2 1

Database Multiple Table Join Queries

I really don't know what queries to be combined using these table to achieve my coressponding output please assist me
Table 1
w_ref t_id q_id qty
110 111 500 1
111 112 500 2
112 113 500 3
Table 2
t_id q_id material-x material-y material_id
111 500 14 15 7
112 500 18 18 7
113 500 10 11 8
Table 3
id material_name
7 abc
8 def
I expect that joining table output like this
Output
w_ref qty material-x material-y material_name
110 1 14 15 abc
111 2 18 07 abc
112 3 10 11 def
Here is a simple example of a SQL of a INNER JOIN. This will give you a basic understanding from the results given.
SELECT a.w_ref, a.t_id, a.q_id, a.qty, b.material-x FROM table1 a INNER JOIN table2 b ON b.t_id = a.t_id;
However their is very little of what you're trying to achieve and should not just post a question asking someone to sort it. Maybe add what you have tried so far and what outcomes you have had.

Latest record for each user number?

I did search, but the uniqueness of each question makes it hard for me to "translate" it for my dataset.
I have table A named: CLOGS17
With a sub-set of the data and fields shown:
SERIALNO EVDATE SYSNO AREA USRNO
4 2017-01-01 02:03:48.000 1 4 10
4 2017-01-01 02:09:00.000 1 4 10
4 2017-01-01 02:24:44.997 1 6 10
4 2017-01-01 02:56:50.000 1 2 18
5 2017-08-08 02:03:48.000 1 4 10
5 2017-01-09 02:09:00.000 1 4 10
6 2017-04-03 02:24:44.997 1 6 10
8 2017-05-05 02:56:50.000 1 2 18
My goal is to retrieve all records where the combination of SERIALNO + SYSNO + AREA + USRNO has not been used in the last 30 days (inactive user essentiallY) so I can delete that USRNO.
Desired output from above data would be (newest record for each SERIALNO, SYSNO, AREA, and USRNO distinct combination):
SERIALNO EVDATE SYSNO AREA USRNO
4 2017-01-01 02:09:00.000 1 4 10
4 2017-01-01 02:24:44.997 1 6 10
4 2017-01-01 02:56:50.000 1 2 18
5 2017-08-08 02:03:48.000 1 4 10
6 2017-04-03 02:24:44.997 1 6 10
8 2017-05-05 02:56:50.000 1 2 18
I am then able to get only those within the last 30 days.
Given the table data below ("Table B"), it is a list of all stored users:
SERIALNO CONTID SYSNO AREA USRID
36 001 1 * 1
36 001 1 * 18
36 001 1 * 2
36 001 1 * 29
36 001 1 * 36
36 001 1 1 10
This table contains ALL users in the system.
How can I return all the users from Table B that have not been used for a given CONTID, SYSNO, and AREA?
For the first part of your question it would be as simples as a group by of a select on the desired fields:
SELECT SERIALNO,
SYSNO,
AREA,
USRNO,
MAX(EVDATE)
FROM CLOGS17
GROUP BY SERIALNO,
SYSNO,
AREA,
USRNO
Since you didn't provide enough information about the second part. This query will give you the output you show in your question.
So, to get all users that doesn't meet your 30 days criteria (whatever it are), you just do a left join of you user table with the above query seeking the nulls for the query above, like this:
SELECT *
FROM tableb tb LEFT JOIN
(SELECT SERIALNO,
SYSNO,
AREA,
USRNO,
MAX(EVDATE)
FROM CLOGS17
GROUP BY SERIALNO,
SYSNO,
AREA,
USRNO) a
ON tb.SERIALNO = a.SERIALNO,
AND tb.SYSNO = a.SYSNO
AND tb.USRNO = a.USRNO
WHERE a.AREA is null

compare two tables and add result in second table

I have been working on comparing two almost identical tables and update/add the result in second table. Here are the two tables i am using. Person1(ID,Name,PHNumber) and Person2(ID,Name,PHNumber,IsActive).
Note: person1 has always a more/less/same rows than person2.Person1 is reference table we need to add/delete the rows which does/doesnot present in person1 int to person2. I am using microsoft SQL server management studio.
Case1: If the compared result has more rows(Let say person1 has 10, person2 has 8rows) then we need to add those(2rows) to person2 and keep IsActive-1 for those rows.
Case2: If the compared result has differnce(Let say person1 has 10 but person2 has 20rows) then we need to find those delta 10rows and keep IsActive-0 for those 10rows.
Hope the query is clear and expecting your valuable solutions. Thank you.
Here Person1 does not contain newdata2 and contains newdata,newdata1 which are
new values after comparing, so we are giving IsActive-0 and IsActive-1
respectively.
Person1:
ID Name PHNumber
1 missouri 123
2 kansas 111
3 stlouise 234
4 california 456
5 india 888
6 srilanka 780
7 dallas 890
8 texas 1111
9 mario 1112
10 sister 7878
11 pontiac 8765
12 newdata 1234
13 newdata1 2345
Person2:
ID Name PHNumber IsActive
1 missouri 123 1
2 kansas 111 1
3 stlouise 234 1
4 california 456 1
5 india 888 1
6 srilanka 780 1
7 dallas 890 1
8 texas 1111 1
9 mario 1112 1
10 sister 7878 1
11 pontiac 8765 1
12 newdata2 987 1
RESULT: Person2:
ID Name PHNumber IsActive
1 missouri 123 1
2 kansas 111 1
3 stlouise 234 1
4 california 456 1
5 india 888 1
6 srilanka 780 1
7 dallas 890 1
8 texas 1111 1
9 mario 1112 1
10 sister 7878 1
11 pontiac 8765 1
12 newdata2 987 0
13 newdata 1234 1
14 newdata1 2345 1
If you are still looking or answer, you can try like this...
;WITH cte
AS (SELECT
COALESCE(p1.id, p2.id) AS id,
COALESCE(p1.name, p2.name) AS name,
COALESCE(p1.phnumber, p2.phnumber) AS phnumber,
CASE WHEN p1.name IS NULL THEN 0 ELSE 1 END AS IsActive
FROM Person1 p1
FULL JOIN person2 p2
ON p1.name = p2.name
AND p1.phnumber = p2.phnumber)
SELECT
ROW_NUMBER() OVER (ORDER BY id, phnumber) AS id,
name, phnumber, IsActive
FROM cte

SQL Server order by syntax with Case When and a Constant

I'm reading TSQL code someone else wrote and find a somewhat weird syntax. It's doing order by a string. I did some test and the following is the code. Anyone can help me to explain it? Thanks.
First Query
SELECT *
FROM dbo.Products
Result:
ProductID ProductName SupplierID CategoryID QuantityPerUnit UnitPrice UnitsInStock UnitsOnOrder ReorderLevel Discontinued
----------- ------------------------------- ----------- ----------- -------------------- --------------------- ------------ ------------ ------------ ------------
1 Chai 1 1 10 boxes x 20 bags 18.00 39 0 10 0
2 Chang 1 1 24 - 12 oz bottles 19.00 17 40 25 0
3 Aniseed Syrup 1 2 12 - 550 ml bottles 10.00 13 70 25 0
4 Chef Anton's Cajun Seasoning 2 2 48 - 6 oz jars 22.00 53 0 0 0
...
*/
Second query:
SELECT *
FROM dbo.Products
WHERE ProductID < 10
ORDER BY '3';
Result:
Msg 408, Level 16, State 1, Line 1 A constant expression was
encountered in the ORDER BY list, position 1.
Third Query
SELECT *
FROM dbo.Products
WHERE ProductID < 10
ORDER BY CASE WHEN SupplierID = 2 THEN '1'
WHEN SupplierID = 1 THEN '2'
ELSE '3'
END;
Result:
ProductID ProductName SupplierID CategoryID QuantityPerUnit UnitPrice UnitsInStock UnitsOnOrder ReorderLevel Discontinued
----------- ---------------------------------------- ----------- ----------- -------------------- --------------------- ------------ ------------ ------------ ------------
4 Chef Anton's Cajun Seasoning 2 2 48 - 6 oz jars 22.00 53 0 0 0
5 Chef Anton's Gumbo Mix 2 2 36 boxes 21.35 0 0 0 1
1 Chai 1 1 10 boxes x 20 bags 18.00 39 0 10 0
2 Chang 1 1 24 - 12 oz bottles 19.00 17 40 25 0
3 Aniseed Syrup 1 2 12 - 550 ml bottles 10.00 13 70 25 0
6 Grandma's Boysenberry Spread 3 2 12 - 8 oz jars 25.00 120 0 25 0
7 Uncle Bob's Organic Dried Pears 3 7 12 - 1 lb pkgs. 30.00 15 0 10 0
8 Northwoods Cranberry Sauce 3 2 12 - 12 oz jars 40.00 6 0 0 0
9 Mishi Kobe Niku 4 6 18 - 500 g pkgs. 97.00 29 0 0 1
(9 row(s) affected)
*/
"Order by" has to be able to translate each row into a value, then those values can be compared. "Order by '3'" doesn't make any sense as a useful query, as it's not using the row - hence the error message of ordering by a constant expression.
"Order by (some expression returning a string)" makes perfect sense. I would personally have used numbers rather than strings, but fundamentally it's still just ordering by a value.
Would you have found it odd to see "order by ProductName"? That's ordering by a string too.
Hopefully that helps - it's not really clear which bit was causing a problem though.
In your first SQL query, the original coder might have meant
ORDER BY 3
which means "order by the 3rd column" (which is SupplierId), in ascending order.
In the second query, as #Kokizzo has explained, the author has hard coded the query so that Products from supplierId 2 are at the top, followed by those from supplierId 1, and then all rows from other suppliers. The purpose isn't clear, but for example, this could be a nefarious attempt to promote a certain supplier's products above others e.g. in a web search result page.
The CASE WHEN .. ELSE ... END can be equated to a simple function applied to each row, which takes the supplierId as input and returns the precedence of that row used in the ORDER BY clause.
CASE WHEN SupplierID = 2 THEN '1'
WHEN SupplierID = 1 THEN '2'
ELSE '3'
END
is equal to (in pseudocode):
if supplierId = 2 then
order_value = 1
else if supplierId = 1 then
order_value = 2
else
order_value = 3
end
so the order now is according to the order_value

Resources