I have a table structure as follows..
and here is sample data...
tblTeam
----------------------------------
Name TeamID
Royal Challengers Bangalore 1
Chennai Super Kings 2
Delhi Daredevils 3
Sunrisers Hyderabad 4
Kolkata Knight Riders 5
Mumbai Indians 6
Kings XI Punjab 7
Rajasthan Royals 8
Deccan Chargers 9
Kochi Tuskers Kerala 10
Pune Warriors 11
------------------------------------------------
tblSchedule
------------------------------------------------
ScheduleID DateTime Team_1 Team_2 VenuID
1 4/18/08 8:00 PM 1 5 6
2 4/19/08 5:00 PM 2 7 9
3 4/19/08 8:30 PM 3 8 4
4 4/20/08 4:30 PM 5 9 1
5 4/20/08 8:00 PM 1 6 5
6 4/21/08 8:00 PM 8 7 27
7 4/22/08 8:00 PM 3 9 10
8 4/23/08 8:00 PM 2 6 2
9 4/24/08 8:00 PM 8 9 10
10 4/25/08 8:00 PM 6 7 9
11 4/26/08 4:00 PM 5 2 2
12 4/26/08 8:00 PM 1 8 6
-----------------------------------------------
The yellow key in the pic denote primary key and blue one foreign key.
and my requirement is like this....
DateTime Team-1 Team-2
Apr 8, 2015 8:00:00 PM Kolkata Knight Riders Mumbai Indians
Please help to get that o/p...
Join tblTeam twice with different alias names (T1 & T2):
SELECT ScheduleID,DateTime,T1.Name as [Team-1],T2.Name as [Team-2]
FROM tblSchedule S JOIN
tblTeam T1 ON S.Team_1=T1.TeamID JOIN
tblTeam T2 ON S.Team_2=T2.TeamID
ORDER BY S.ScheduleID
Sample Result:
ScheduleID DateTime Team-1 Team-2
----------------------------------------------------------------------------------------
1 April, 18 2008 20:00:00 Royal Challengers Bangalore Kolkata Knight Riders
2 April, 19 2008 17:00:00 Chennai Super Kings Kings XI Punjab
3 April, 19 2008 20:30:00 Delhi Daredevils Rajasthan Royals
4 April, 20 2008 16:30:00 Kolkata Knight Riders Deccan Chargers
5 April, 20 2008 20:00:00 Royal Challengers Bangalore Mumbai Indians
Sample result in SQL Fiddle
I like to use subquery for this type of problem to avoid the extra joining
product.
SELECT
CONVERT(varchar(20), DateTime, 100) AS DateTime,
(SELECT Name FROM tblTeam WHERE s.Team_1 = TeamID) AS Team-1,
(SELECT Name FROM tblTeam WHERE s.Team_2 = TeamID) AS Team-2
FROM tblSchedule s
Extra reading
Related
I want to find BETWEEN time but not show result.im share database please share valuable idea....
SQL code
SELECT *
FROM ci_time_slot
WHERE type like '%B%'
and sloat_name BETWEEN '8:00 AM' and '12:00 PM'
table
id sloat_name type
1 8:00 AM A,B,C,D
2 8:15 AM A
3 8:30 AM A,B
4 8:45 AM A,C
5 9:00 AM A,B,D
6 9:15 AM A
7 9:30 AM A,B,C
8 9:45 AM A
9 10:00 AM A,B,D
10 10:15 AM A,C
11 10:30 AM A,B
12 10:45 AM A
13 11:00 AM A,B,C,D
14 11:15 AM A
15 11:30 AM A,B
16 11:45 AM A,C
17 12:00 PM A,B,D
need result
show this type of result depend on time
id sloat_name type
1 8:00 AM A,B,C,D
2 8:15 AM A
3 8:30 AM A,B
4 8:45 AM A,C
5 9:00 AM A,B,D
6 9:15 AM A
7 9:30 AM A,B,C
8 9:45 AM A
9 10:00 AM A,B,D
10 10:15 AM A,C
11 10:30 AM A,B
12 10:45 AM A
13 11:00 AM A,B,C,D
14 11:15 AM A
15 11:30 AM A,B
16 11:45 AM A,C
17 12:00 PM A,B,D
You haven't mentioned yet which dbms are you using ,I'm using MySQL for demonstration. You have to cast sloat_name to time to use between.
Try :
SELECT c.*
FROM ci_time_slot c
WHERE type like '%B%'
and cast(sloat_name as time) between '08:00:00' and '12:00:00';
Result:
id sloat_name type
1 8:00 AM A,B,C,D
3 8:30 AM A,B
5 9:00 AM A,B,D
7 9:30 AM A,B,C
9 10:00 AM A,B,D
11 10:30 AM A,B
13 11:00 AM A,B,C,D
15 11:30 AM A,B
17 12:00 PM A,B,D
Demo
I want to filter a TableA, taking into account only those rows whose "TotalInvoice" field is within the minimum and maximum values expressed in a ViewB, based on month and year values and RepairShopId (the sample data only has one RepairShopId, but all the data has multiple IDs).
In the view I have minimum and maximum values for each business and each month and year.
TableA
RepairOrderDataId
RepairShopId
LastUpdated
TotalInvoice
1
10
2017-06-01 07:00:00.000
765
1
10
2017-06-05 12:15:00.000
765
2
10
2017-02-25 13:00:00.000
400
3
10
2017-10-19 12:15:00.000
295679
4
10
2016-11-29 11:00:00.000
133409.41
5
10
2016-10-28 12:30:00.000
127769
6
10
2016-11-25 16:15:00.000
122400
7
10
2016-10-18 11:15:00.000
1950
8
10
2016-11-07 16:45:00.000
79342.7
9
10
2016-11-25 19:15:00.000
1950
10
10
2016-12-09 14:00:00.000
111559
11
10
2016-11-28 10:30:00.000
106333
12
10
2016-12-13 18:00:00.000
23847.4
13
10
2016-11-01 17:00:00.000
22782.9
14
10
2016-10-07 15:30:00.000
NULL
15
10
2017-01-06 15:30:00.000
138958
16
10
2017-01-31 13:00:00.000
244484
17
10
2016-12-05 09:30:00.000
180236
18
10
2017-02-14 18:30:00.000
92752.6
19
10
2016-10-05 08:30:00.000
161952
20
10
2016-10-05 08:30:00.000
8713.08
ViewB
RepairShopId
Orders
Average
MinimumValue
MaximumValue
year
month
yearMonth
10
1
370343
370343
370343
2015
7
2015-7
10
1
109645
109645
109645
2015
10
2015-10
10
1
148487
148487
148487
2015
12
2015-12
10
1
133409.41
133409.41
133409.41
2016
3
2016-3
10
1
19261
19261
19261
2016
8
2016-8
10
4
10477.3575
2656.65644879821
18298.0585512018
2016
9
2016-9
10
69
15047.709565
10
90942.6052417394
2016
10
2016-10
10
98
22312.077244
10
147265.581935242
2016
11
2016-11
10
96
20068.147395
10
99974.1750708773
2016
12
2016-12
10
86
25334.053372
10
184186.985160105
2017
1
2017-1
10
69
21410.63855
10
153417.00126689
2017
2
2017-2
10
100
13009.797
10
59002.3589332934
2017
3
2017-3
10
101
11746.191287
10
71405.3391452842
2017
4
2017-4
10
123
11143.49756
10
55306.8202091131
2017
5
2017-5
10
197
15980.55406
10
204538.144334771
2017
6
2017-6
10
99
10852.496969
10
63283.9899761938
2017
7
2017-7
10
131
52601.981526
10
1314998.61355187
2017
8
2017-8
10
124
10983.221854
10
59444.0535811233
2017
9
2017-9
10
115
12467.148434
10
72996.6054527277
2017
10
2017-10
10
123
14843.379593
10
129673.931373139
2017
11
2017-11
10
111
8535.455945
10
50328.1495501884
2017
12
2017-12
I've tried:
SELECT *
FROM TableA
INNER JOIN ViewB ON TableA.RepairShopId = ViewB.RepairShopId
WHERE TotalInvoice > MinimumValue AND TotalInvoice < MaximumValue
AND TableA.RepairShopId = ViewB.RepairShopId
But I'm not sure how to compare it the yearMonth field with the datetime field "LastUpdated".
Any help is very appreciated!
here is how you can do it:
I assumed LastUpdated column is the column from tableA which indicate date of
SELECT *
FROM TableA A
INNER JOIN ViewB B
ON A.RepairShopId = B.RepairShopId
AND A.TotalInvoice > B.MinimumValue
AND A.TotalInvoice < B.MaximumValue
AND YEAR(LastUpdated) = B.year
AND MONTH(LastUpdated) = B.month
Am new to Sql queries. I need to build a query which will rank the student based on number of test on which he has got 100% divide by total number of test he has taken and consider only test which are 10 days old. Here is my table structure.
CREATE TABLE student(
id serial NOT NULL,student_email varchar NULL,
student_name varchar NULL,
test_subject varchar NULL,
total_question varchar NULL,
total_passed varchar NULL,
total_failed varchar NULL,
total_skipped varchar NULL,
test_time timestamp NULL,
CONSTRAINT student PRIMARY KEY (id));
if a student has total_failed or total_skipped not 0 then that test is not considered has 100%.
sample data will be like
1 j#b.com john maths 10 10 0 0 2019-08-20 21:00:00
2 j#b.com john maths 10 10 0 0 2019-08-19 21:00:00
3 j#b.com john maths 10 09 1 0 2019-08-18 21:00:00
4 j#b.com john english 10 10 0 0 2019-08-20 21:00:00
5 j#b.com john english 10 10 0 0 2019-08-19 21:00:00
6 j#b.com john english 10 09 0 1 2019-08-20 21:00:00
7 p#b.com paul maths 10 10 0 0 2019-08-20 21:00:00
8 p#b.com paul maths 10 10 0 0 2019-08-19 21:00:00
9 p#b.com paul maths 10 10 0 0 2019-08-18 21:00:00
10 k#b.com koki maths 10 10 0 0 2019-06-20 21:00:00
11 k#b.com koki english 10 10 0 0 2019-06-20 21:00:00
12 k#b.com koki science 10 10 0 0 2019-08-20 21:00:00
13 k#b.com koki maths 10 08 2 0 2019-08-20 21:00:00
14 k#b.com koki english 10 10 0 0 2019-08-20 21:00:00
from the above data set i need to consider only those data which are with in 10 days and give the "RANK" based on total number of test with 100% divided by total number of test for every distinct subject_name,student.
output of above dataset will be
koki science 100% k#b.com
koki english 100% k#b.com
paul maths 100% p#b.com
john maths 66.6% j#b.com
john english 66.6% j#b.com
koki science 0% k#b.com
Any help appreciated
When I
translate your definition of rank:
total number of test with 100% divided by total number of test
as
COUNT(*) FILTER (WHERE total_passed = total_question) / COUNT(*)::real
and apply the filter for the last 10 days:
test_time > CURRENT_DATE - interval '10 days'
I end up with the following query
SELECT
student_name
, test_subject
, COUNT(*) FILTER (WHERE total_passed = total_question) / COUNT(*)::real student_rank
FROM student
WHERE test_time > CURRENT_DATE - interval '10 days'
GROUP BY 1, 2
ORDER BY 3 desc;
I get the desired output:
student_name | test_subject | student_rank
--------------+--------------+-------------------
paul | maths | 1
koki | english | 1
koki | science | 1
john | maths | 0.666666666666667
john | english | 0.666666666666667
koki | maths | 0
(6 rows)
You can use conditional aggregation. In this case, avg() should work:
select student_name, test_subject,
avg( (total_failed + total_skipped = 0)::int ) as ratio_passed
from t
where test_time > now() - interval 10 day
group by student_name, test_subject;
I am trying to get either live temperature for a trip, if live data is not available get an average temperature from histroical data.
I have made a simple version of my problem, with these tabels:
Trip
id departure_time arrival_time location_id
1 2018-04-07 07:00:00 2018-04-14 17:00:00 1
2 2018-04-14 07:00:00 2018-04-21 17:00:00 1
Location
id name
1 Location
Weather
id temperature date location_id
1 20 2018-04-07 1
2 20 2018-04-08 1
3 20 2018-04-09 1
4 20 2018-04-10 1
5 20 2018-04-11 1
6 20 2018-04-12 1
7 20 2018-04-13 1
8 20 2018-04-14 1
9 15 2016-04-07 1
10 15 2016-04-08 1
11 15 2016-04-09 1
12 15 2016-04-10 1
13 15 2016-04-11 1
14 15 2016-04-12 1
15 15 2016-04-13 1
16 15 2016-04-14 1
17 19 2017-04-07 1
18 19 2017-04-08 1
19 19 2017-04-09 1
20 19 2017-04-10 1
21 19 2017-04-11 1
22 19 2017-04-12 1
23 19 2017-04-13 1
24 19 2017-04-14 1
25 15 2017-04-15 1
26 15 2017-04-16 1
27 15 2017-04-17 1
28 15 2017-04-18 1
29 15 2017-04-19 1
30 15 2017-04-20 1
31 15 2017-04-21 1
32 19 2016-04-15 1
33 19 2016-04-16 1
34 19 2016-04-17 1
35 19 2016-04-18 1
36 19 2016-04-19 1
37 19 2016-04-20 1
38 19 2016-04-21 1
The problem i am having is that since these trips are last-minute trips i have "live" data for trips departing within the next week.
So i would like to get a either live forecast if available, else an avg for the temperature from the years from the previous years.
http://sqlfiddle.com/#!17/bce59/3
Here is the approach i took in order to try and solve the problem.
If any details has been forgotten please ask.
Expected result:
id departure_time arrival_time location_id temperature
1 2018-04-07 07:00:00 2018-04-14 17:00:00 1 20
1 2018-04-07 07:00:00 2018-04-14 17:00:00 1 20
1 2018-04-07 07:00:00 2018-04-14 17:00:00 1 20
1 2018-04-07 07:00:00 2018-04-14 17:00:00 1 20
1 2018-04-07 07:00:00 2018-04-14 17:00:00 1 20
1 2018-04-07 07:00:00 2018-04-14 17:00:00 1 20
1 2018-04-07 07:00:00 2018-04-14 17:00:00 1 20
1 2018-04-07 07:00:00 2018-04-14 17:00:00 1 20
2 2018-04-14 07:00:00 2018-04-21 17:00:00 1 20
2 2018-04-14 07:00:00 2018-04-21 17:00:00 1 17
2 2018-04-14 07:00:00 2018-04-21 17:00:00 1 17
2 2018-04-14 07:00:00 2018-04-21 17:00:00 1 17
2 2018-04-14 07:00:00 2018-04-21 17:00:00 1 17
2 2018-04-14 07:00:00 2018-04-21 17:00:00 1 17
2 2018-04-14 07:00:00 2018-04-21 17:00:00 1 17
2 2018-04-14 07:00:00 2018-04-21 17:00:00 1 17
Using generate_series function to make a Calendar from trip table on subquery.
Then Left JOIN on subquery by dates you might get match weather you can get it temperature. if temperature is null on w.temperature then get avg temperature
You can try this.
SELECT t.id,
t.departure_time,
t.arrival_time,
l.id as "location_id",
coalesce(w.temperature,(select FLOOR(avg(temperature)) from weather)) as "temperature"
FROM
location l inner join
(
select id,
location_id,
departure_time,
arrival_time,
generate_series(departure_time :: timestamp,arrival_time::timestamp,'1 day'::interval) as dates
from trip
) t on t.location_id = l.id LEFT JOIN weather w on t.dates::date = w.date::date
sqlfiddle:http://sqlfiddle.com/#!17/bce59/48
EDIT
You could use a CTE query get Avg by year instead of the subquery in coalesce function on select clause.
WITH weather_avg AS (
SELECT floor(avg(a)) avgTemp
from
(
SELECT
extract(YEAR from weather.date) AS YEAR,
floor(avg(weather.temperature)) a
FROM weather
group by extract(YEAR from weather.date)
) t
)
SELECT t.id,
t.departure_time,
t.arrival_time,
t.location_id as "location_id",
coalesce(w.temperature,(select avgTemp from weather_avg)) as "temperature"
FROM
(
select t.id,
t.location_id,
t.departure_time,
t.arrival_time,
generate_series(departure_time :: timestamp,arrival_time::timestamp,'1 day'::interval) as dates
from trip t inner join location l on t.location_id = l.id
) t LEFT JOIN weather w
on t.dates::date = w.date::date
sqlfiddle:http://sqlfiddle.com/#!17/bce59/76
4I have these tables :
day_shift
id_dshift dshift_name on_duty off_duty in_start in_end out_start out_end workday
1001 ds_normal 7:00 15:00 7:00 10:00 11:00 20:00 1
1002 ds_Saturday 7:00 14:00 7:00 10:00 11:00 14:00 1
week_shift
id_wshift wshift_name mon tue wed thu fri sat sun
2001 ws_normal 1001 1001 1001 1001 1001 1002 1001
2002 ws_2013_w1 0 1001 1001 1001 1001 1001 0
2003 ws_2013_w2 1003 1001 1001 1001 1001 1002 1001
daily_attendance
emp_id checkdate in out emp_shift_id
10 15/06/2013 7:10 15:05 2001 <-- saturday
10 16/06/2013 7:05 15:03 2001 <-- sunday
what I want is having a result like this :
emp_id checkdate in out on_duty off_duty
10 15/06/2013 7:10 15:05 07:00 14:00
10 16/06/2013 7:30 14:30 07:00 15:00
in first row of daily_attendance, since the weekday is saturday so i want to get the value of week_shift.sat (1002)
if the weekday is sunday, i want to get the value of week_shift.sun (1001)
so I get the on_duty and off_duty values from day_shift
How to do it in query?
The trick here would be to create a saved query in Access named [week_shift_transformed] to transform your [week_shift] table into separate rows for each day of the week:
SELECT id_wshift, wshift_name, 1 AS [weekday], [sun] as id_dshift FROM week_shift
UNION ALL
SELECT id_wshift, wshift_name, 2 AS [weekday], [mon] as id_dshift FROM week_shift
UNION ALL
SELECT id_wshift, wshift_name, 3 AS [weekday], [tue] as id_dshift FROM week_shift
UNION ALL
SELECT id_wshift, wshift_name, 4 AS [weekday], [wed] as id_dshift FROM week_shift
UNION ALL
SELECT id_wshift, wshift_name, 5 AS [weekday], [thu] as id_dshift FROM week_shift
UNION ALL
SELECT id_wshift, wshift_name, 6 AS [weekday], [fri] as id_dshift FROM week_shift
UNION ALL
SELECT id_wshift, wshift_name, 7 AS [weekday], [sat] as id_dshift FROM week_shift
That will give you
id_wshift wshift_name weekday id_dshift
--------- ----------- ------- ---------
2001 ws_normal 1 1001
2002 ws_2013_w1 1 0
2003 ws_2013_w2 1 1001
2001 ws_normal 2 1001
2002 ws_2013_w1 2 0
2003 ws_2013_w2 2 1003
2001 ws_normal 3 1001
2002 ws_2013_w1 3 1001
2003 ws_2013_w2 3 1001
2001 ws_normal 4 1001
2002 ws_2013_w1 4 1001
2003 ws_2013_w2 4 1001
2001 ws_normal 5 1001
2002 ws_2013_w1 5 1001
2003 ws_2013_w2 5 1001
2001 ws_normal 6 1001
2002 ws_2013_w1 6 1001
2003 ws_2013_w2 6 1001
2001 ws_normal 7 1002
2002 ws_2013_w1 7 1001
2003 ws_2013_w2 7 1002
Then you can use a query like this:
SELECT da.emp_id, da.checkdate, da.in, da.out, ds.on_duty, ds.off_duty
FROM
daily_attendance da
INNER JOIN
(
week_shift_transformed wtt
INNER JOIN
day_shift ds
ON ds.id_dshift = wtt.id_dshift
)
ON wtt.weekday = Weekday(da.checkdate)
AND wtt.id_wshift = da.emp_shift_id