Database Multiple Table Join Queries - database

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.

Related

SQL - Select non repeating columns

I have a table like
id name R_id mgr_id
----------------------------
61 a 22 1
62 a 22 2
62 b 23 1
63 c 24 4
63 b 22 3
64 c 25 3
and I would like to get the following result set
R_id mgr_id
--------------
22 1
23 1
24 4
25 3
I would like select repeating R_ids only once
I tried using this query but with not much success, can anyone help me.
SELECT DISTINCT R_id, mgr_id from DT
Perhaps something like this... WITH TIES clause in concert with Row_NUmber()
Example
Select Top 1 with ties
R_ID
,mgr_id
From #YourTable
Order By Row_Number() over (Partition By R_ID order by Mgr_id)
Returns
R_ID mgr_id
22 1
23 1
24 4
25 3

select timestamps within ranges

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

How to pull consecutive months data in sql server even if there is null value

I'm newbie trying to create a SQL query to find how much each Theater has sold the tickets per month during previous year (i.e. for all 12 months). If the collection amount is null or blank I need to produce an output as Zero of any such given month in that year.
I have two tables as below mentioned:
TABLE 1:
Month_Number Year
1 2016
2 2016
3 2016
4 2016
5 2016
6 2016
7 2016
8 2016
9 2016
10 2016
11 2016
12 2016
TABLE 2:
Theater month Amount_In_Thousands
ABC 1 165
ABC 3 70
ABC 4 102
GHI 1 45
GHI 2 70
GHI 3 42
GHI 4 57
ABC 6 122
ABC 7 67
ABC 8 22
ABC 9 80
ABC 11 46
ABC 12 38
You might have noticed for 'ABC' Theater there is 0 or null values for month 2, month 5 and month 10. I am unable to produce these missing months with zero value. I tried with simple left outer join but still the data output row doesn't show with month/year and zero value.
I need to produce the output as below:
OUTPUT
Movie_Theators Month Amount_In_Thounds
ABC 1 165
ABC 2 0 *
ABC 3 70
ABC 4 102
ABC 5 0 *
ABC 6 122
ABC 7 67
ABC 8 22
ABC 9 80
ABC 10 0 *
ABC 11 46
ABC 12 38
GHI 1 45
GHI 2 70
GHI 3 42
GHI 4 57
Can anybody please help me how to write sql script in order to produce the output as shown above. Thank you so much in advance.
You can use a CROSS JOIN between every theater and month-year, and then perform a LEFT JOIN with Table2:
SELECT A.Theater,
B.Month_Number,
B.[Year],
ISNULL(C.Amount_In_Thousands,0) Amount_In_Thousands
FROM ( SELECT DISTINCT Theater
FROM dbo.Table2) A -- or use a dbo.Theater table if you have one
CROSS JOIN dbo.Table1 B
LEFT JOIN dbo.Table2 C
ON A.Theater = C.Theater
AND B.Month_Number = C.[month]
AND B.[Year] = C.[Year];

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

Query is very slow

I have tables
table1
epid etid id EValue reqdate
----------- ----------- ----------- ------------ ----------
15 1 1 498925307069 2012-01-01
185 1 2 A5973FC43CE3 2012-04-04
186 1 2 44C6A4B776A2 2012-04-05
205 1 2 7A0ED3F1DA13 2012-09-19
206 1 2 77771D65F9C4 2012-09-19
207 1 2 AD74A4AA41BD 2012-09-19
208 1 2 9595ABE5A0C8 2012-09-19
209 1 2 7611D2FB395B 2012-09-19
210 1 2 04A510D6067A 2012-09-19
211 1 2 24D43EC268F8 2012-09-19
table2
PEId Id EPId
----------- ----------- -----------
43 9 15
44 10 15
45 11 15
46 12 15
47 13 15
48 14 15
49 15 15
50 16 15
51 17 15
52 18 15
table3
PLId PEId Id ToPayId
----------- ----------- ----------- -----------
71 43 9 1
72 43 9 2
73 44 10 1
74 44 10 2
75 45 11 1
76 45 11 2
77 46 12 1
78 46 12 2
79 47 13 1
80 47 13 2
I want to get one id whose count is less than 8 in table 3 and order by peid in table 2,
I have written query
SELECT Top 1 ToPayId FROM
(
SELECT Count(pl.ToPayId) C, pl.ToPayId
FROM table3 pl
INNER JOIN table2 pe ON pl.peid = pe.peid
INNER JOIN table1 e ON pe.epid = e.epid
WHERE e.EtId=1 GROUP BY pl.ToPayId
) As T
INNER JOIN table2 p ON T.ToPayId= p.Id
WHERE C < 8 ORDER BY p.PEId ASC
This query executes more than 1000 times in stored procedure depends on the entries in user-defined-table-type using while condition.
But it is very slow as we have millions of entries in each table.
Can anyone suggest better query regarding above?
maybe try with the having clause to get rid of the from select
select table2.id as due
from table3 inner join table2 on table2.PEId=table3.PEId...
group by ...
having count(due) <8
order by ...
-> you have a redundant Id column in table3 : seems pretty useless as the couple PEId and Id appears unique so remove it and reduce the size of table 3 by 25% hence improving performance of db
Will.. since you did not provide enough sample data and I am not sure what exactly your business logic is. So that I can just modify the code in blind.
SELECT ToPayId
FROM (
SELECT TOP 1 Count(pl.ToPayId) C, pl.ToPayId, pe.PEId
FROM table3 as pl
INNER JOIN table2 as pe ON pl.peid = pe.peid AND pl.ToPayId = pe.Id
INNER JOIN table1 e ON pe.epid = e.epid
WHERE e.EtId=1
GROUP BY pl.ToPayId, pe.PEId
HAVING Count(pl.ToPayId) < 8
ORDER BY pe.PEId ASC
) AS T

Resources