It's me again - I have a new homework and I don't get any further.
The task is:
Find out the date of flight(DATE_FLY), flight number(FLY_NR), manufacturer(MANUF), type (TYP) and serial number (SER_NR) of all flights that fly from Frankfurt to Dallas between 10.11.2013 and 20.11.2013.
This is the departure_table:
DATE_FLY
FLY_NR
MANUF
TYP
PER_NR
SER_NR
TIME_START
06.07.13
LH-888
Boeing
B747
9fg-he-ztu8
10010071
11.23
08.10.13
LH-238
Airbus
A320
z3et-bwe7
10010072
22.06
13.11.13
LH-341
Boeing
B737
ba23-0012
10010001
10.23
14.11.13
LH-358
Boeing
B737
ba23-0012
10010001
8.17
13.11.13
LH-553
Boeing
B777
xv23-0889
10010002
16.53
15.11.13
LH-421
Boeing
B777
xv56-3142
10010002
14.45
17.11.13
LH-789
Airbus
A330
45-6789
10010003
8.11
14.11.13
LH-112
Boeing
B737
ba23-0034
10010001
8.14
17.11.13
LH-421
Boeing
B777
xv23-0889
10010002
16.26
18.11.13
LH-223
Airbus
A380
ab-45-6xf
10010004
9.45
19.11.13
LH-634
Airbus
A350
5478-awe3
10010005
20.25
18.02.14
LH-238
Airbus
A320
z3et-bwe7
10010072
23.06
And this is the fly_table that I need to join:
FLY_NR
START_FLY
DEST_FLY
TIME_FLY
KM
LH-341
Saarbruecken
Hamburg
1.2
490
LH-358
Saarbruecken
Leipzig
1.1
430
LH-553
Leipzig
Hamburg
.5
290
LH-112
Luxemburg
London
1.1
480
LH-421
Luxemburg
Ankara
2.5
2300
LH-789
Luxemburg
New-York
3.5
8300
LH-223
Frankfurt
Dallas
3.9
8600
LH-634
Frankfurt
Moskau
2.3
2020
LH-888
Frankfurt
Peking
9.5
7780
LH-238
Muenchen
Berlin
1.1
479
I wrote the following query but it showed me "no data found":
select
dp.date_fly, dp.fly_nr, dp.manuf, dp.typ, dp.ser_nr
from
departure_table dp, fly_table fl
where
dp.fly_nr = fl.fly_nr
and start_fly = 'Frankfurt'
and dest_fly = 'Dallas'
and dp.date_fly between 10.11.2013 and 20.11.2013;
I've tried a simple join but I still only got the message "no data found":
select
dp.date_fly, dp.fly_nr, dp.manuf, dp.typ, dp.ser_nr
from
departure_table dp, fly_table fl
where
dp.fly_nr = fl.fly_nr;
I don't know what am I doing wrong... I would be very thankful if somebody could help to solve this problem with the join function.
I need to get this result:
DATE_FLY
FLY_NR
MANUF
TYP
SER_NR
18-NOV-13
LH-223
Airbus
A380
10010004
Thank you!
The column FLY_DATE has a VARCHAR2 format
This is bad practice. If you have a date then store it as a date. If you have to store it as a string (really, don't do that) then store it using ISO8601 formatting YYYY-MM-DD which can be sorted alphabetically into date-order (and not DD-MM-YYYY which cannot be easily sorted).
Since you have it in a (mostly unusable) string format, you need to convert it to a DATE using the TO_DATE function and compare it to DATE literals:
select dp.date_fly,
dp.fly_nr,
dp.manuf,
dp.typ,
dp.ser_nr
from departure_table dp
INNER JOIN fly_table fl
ON dp.fly_nr = fl.fly_nr
where start_fly = 'Frankfurt'
and dest_fly = 'Dallas'
and TO_DATE(dp.date_fly, 'DD.MM.YYYY') between DATE '2013-11-10' and DATE '2013-11-20';
Which, for the sample data:
CREATE TABLE departure_table (DATE_FLY, FLY_NR, MANUF, TYP, PER_NR, SER_NR, TIME_START) AS
SELECT '06.07.2013', 'LH-888', 'Boeing', 'B747', '9fg-he-ztu8', 10010071, 11.23 FROM DUAL UNION ALL
SELECT '08.10.2013', 'LH-238', 'Airbus', 'A320', 'z3et-bwe7', 10010072, 22.06 FROM DUAL UNION ALL
SELECT '13.11.2013', 'LH-341', 'Boeing', 'B737', 'ba23-0012', 10010001, 10.23 FROM DUAL UNION ALL
SELECT '14.11.2013', 'LH-358', 'Boeing', 'B737', 'ba23-0012', 10010001, 8.17 FROM DUAL UNION ALL
SELECT '13.11.2013', 'LH-553', 'Boeing', 'B777', 'xv23-0889', 10010002, 16.53 FROM DUAL UNION ALL
SELECT '15.11.2013', 'LH-421', 'Boeing', 'B777', 'xv56-3142', 10010002, 14.45 FROM DUAL UNION ALL
SELECT '17.11.2013', 'LH-789', 'Airbus', 'A330', '45-6789', 10010003, 8.11 FROM DUAL UNION ALL
SELECT '14.11.2013', 'LH-112', 'Boeing', 'B737', 'ba23-0034', 10010001, 8.14 FROM DUAL UNION ALL
SELECT '17.11.2013', 'LH-421', 'Boeing', 'B777', 'xv23-0889', 10010002, 16.26 FROM DUAL UNION ALL
SELECT '18.11.2013', 'LH-223', 'Airbus', 'A380', 'ab-45-6xf', 10010004, 9.45 FROM DUAL UNION ALL
SELECT '19.11.2013', 'LH-634', 'Airbus', 'A350', '5478-awe3', 10010005, 20.25 FROM DUAL UNION ALL
SELECT '18.02.2014', 'LH-238', 'Airbus', 'A320', 'z3et-bwe7', 10010072, 23.06 FROM DUAL;
CREATE TABLE fly_table (FLY_NR, START_FLY, DEST_FLY, TIME_FLY, KM) AS
SELECT 'LH-341', 'Saarbruecken', 'Hamburg', 1.2, 490 FROM DUAL UNION ALL
SELECT 'LH-358', 'Saarbruecken', 'Leipzig', 1.1, 430 FROM DUAL UNION ALL
SELECT 'LH-553', 'Leipzig', 'Hamburg', .5, 290 FROM DUAL UNION ALL
SELECT 'LH-112', 'Luxemburg', 'London', 1.1, 480 FROM DUAL UNION ALL
SELECT 'LH-421', 'Luxemburg', 'Ankara', 2.5, 2300 FROM DUAL UNION ALL
SELECT 'LH-789', 'Luxemburg', 'New-York', 3.5, 8300 FROM DUAL UNION ALL
SELECT 'LH-223', 'Frankfurt', 'Dallas', 3.9, 8600 FROM DUAL UNION ALL
SELECT 'LH-634', 'Frankfurt', 'Moskau', 2.3, 2020 FROM DUAL UNION ALL
SELECT 'LH-888', 'Frankfurt', 'Peking', 9.5, 7780 FROM DUAL UNION ALL
SELECT 'LH-238', 'Muenchen', 'Berlin', 1.1, 479 FROM DUAL;
Outputs:
DATE_FLY
FLY_NR
MANUF
TYP
SER_NR
18.11.2013
LH-223
Airbus
A380
10010004
fiddle
I need a way to round in T-SQL (SQL Server 2005).
0.0041 -> 0.005
0.0049 -> 0.005
0.0040 -> 0.004
I have tried the following select with ROUND():
SELECT ROUND(0.004, 3,1) + .001
The problem is: it doesn't work with 0.0040 -> 0.004
This:
SELECT CEILING(1000 * 0.0041) / 1000.0
produces:
0.005
whereas this:
SELECT CEILING(1000 * 0.004) / 1000.0
produces:
0.004
Try this:
SELECT X
, CEILING(X * 1000) / 1000 AS X4
FROM (
SELECT 0.0041 X UNION ALL
SELECT 0.0049 UNION ALL
SELECT 0.0040 ) A
Output:
X X4
--------------------------------------- ---------------------------------------
0.0041 0.005000
0.0049 0.005000
0.0040 0.004000
If a decimal value is 0.40 I'd like to TO_CHAR(0.40) and get '0.40' back. Likewise, 50 should be to_char'd to '50'. As simple as what goes in, comes out, but as a CHAR, in all cases. So far I've tried the following:
select to_char(a, '99D90') test1,
to_char(a, '90D90') test2,
to_char(a, 'FM90D99') test3,
rtrim(to_char(a, 'FM90D99'), to_char(0, 'D')) test4
from (
select 50 a from dual
union all select 50.57 from dual
union all select 5.57 from dual
union all select 0.35 from dual
union all select 0.4 from dual
union all select 0.80 from dual
union all select .88 from dual
)
order by a;
returns:
TEST1 TEST2 TEST3 TEST4
------ ------ ------ ------
.35 0.35 0.35 0.35
.40 0.40 0.4 0.4
.80 0.80 0.8 0.8
.88 0.88 0.88 0.88
5.57 5.57 5.57 5.57
50.00 50.00 50. 50
50.57 50.57 50.57 50.57
As you can see, what may work in one case doesn't in another. Do I have to test for whole numbers, decimal numbers, then leading and trailing zeros and apply a different formatter for each? Is there just a simple cast-like construct? (tried cast too btw, similar issues).
Solved
Oracle does not store or display formatting (even on non-persisted values as shown below). A Formatter must be applied for anything other than that.
0.4, .4 and 0.4000 are all the same. It is just the way you want to display the number.
As I understand, you want to preserve the rows as string, and not just display them. Then you could handle the conditions using a CASE expression.
TRUNC(NUMBER) truncates the decimal portion and gives you a whole number. This will be the driving condition.
So, when TRUNC(NUMBER) = 0, it means it has only decimal part, and we need to append a zero in the beginning, else just convert it into text.
For example,
SQL> WITH DATA AS(
2 select 50 a from dual
3 union all select 50.57 from dual
4 union all select 5.57 from dual
5 union all select 0.35 from dual
6 union all select 0.4 from dual
7 UNION ALL SELECT 0.80 FROM dual
8 UNION ALL SELECT .88 FROM dual
9 )
10 SELECT
11 CASE
12 WHEN TRUNC(A) = 0
13 THEN ltrim(to_char(a, '0D99'), ' ')
14 ELSE TO_CHAR(a)
15 END text
16 FROM DATA;
TEXT
----------------------------------------
50
50.57
5.57
0.35
0.40
0.80
0.88
7 rows selected.
SQL>
Data
I have following partial data
id parent multiplier const
-- ------ ---------- -----
1 NULL 1.10 1.00
2 1 1.20 2.00
3 1 1.30 3.00
4 1 2.40 4.00
5 2 2.50 5.00
6 2 2.60 6.00
7 2 2.70 17.00
8 3 2.80 18.00
9 3 3.90 19.00
10 3 3.10 7.00
11 8 3.20 8.00
12 8 3.30 9.00
13 8 3.40 10.00
14 9 4.50 11.00
15 10 4.60 21.00
15 10 4.70 22.00
Which can be displayed in a tree as following
1
+-- 2
| +-- 5
| +-- 6
| +-- 7
|
+-- 3
| +-- 8
| | +-- 11
| | +-- 12
| | +-- 13
| |
| +-- 9
| | +-- 14
| |
| +-- 10
| +-- 15
| +-- 16
|
+-- 4
SQL to create the table structure and data
DECLARE #table TABLE (Id int, Parent int, multiplier decimal(6,3), Const decimal(6,3));
INSERT INTO #table
SELECT 1, NULL, 1.1, 1.00 UNION
SELECT 2, 1, 1.2, 2.00 UNION
SELECT 3, 1, 1.3, 3.00 UNION
SELECT 4, 1, 2.4, 4.00 UNION
SELECT 5, 2, 2.5, 5.00 UNION
SELECT 6, 2, 2.6, 6.00 UNION
SELECT 7, 2, 2.7, 17.00 UNION
SELECT 8, 3, 2.8, 18.00 UNION
SELECT 9, 3, 3.9, 19.00 UNION
SELECT 10, 3, 3.1, 7.00 UNION
SELECT 11, 8, 3.2, 8.00 UNION
SELECT 12, 8, 3.3, 9.00 UNION
SELECT 13, 8, 3.4, 10.00 UNION
SELECT 14, 9, 4.5, 11.00 UNION
SELECT 15, 10, 4.6, 21.00 UNION
SELECT 15, 10, 4.7, 22.00;
Problem
I need to calculate recursive aX+b formula up to the root for any node in the tree. In other words I need to calculate the formula for child node and move resulting value up to parent as x and continue calculation until I reach root.
For example calculating x=1250.00 for node 14 will be
1.10 * (1.30 *( 3.90 * (4.50 * 1250.00 + 11.00) + 19.00) + 3.00) + 1.00 = 31463.442
Currently I am doing this using CTE tree and a C# however I am not satisfied with its speed and optimization.
Question
Can I do this calculation on SQL server and just return the value? If it is possible, what is the tree depth that I can navigate with CTE?
Can I do this calculation on SQL server and just return the value?
Yes, do the recursion from the leaf node, do the calculation as you go and get the max value in the main query.
with C as
(
select T.Id,
T.Parent,
cast(T.multiplier * #x + T.Const as decimal(19, 3)) as x
from #table as T
where T.Id = 14
union all
select T.Id,
T.Parent,
cast(T.multiplier * C.x + T.Const as decimal(19, 3))
from C
inner join #table as T
on C.Parent = T.Id
)
select max(C.x) as Value
from C
option (maxrecursion 0);
If it is possible, what is the tree depth that I can navigate with
CTE?
Default is 100 but you can change that with maxrecursion. When using option (maxrecursion 0) there is no limit.
I am not satisfied with its speed and optimization.
To fix that you have to show what you actually do. The sample you have provided gets a good plan if you have a clustered primary key on Id.
It does a seek to find the anchor and seeks for each iteration.
I have a table bill with column name bill_id. bill_id value range is from 1 to 40. And I have rows like
bill_id
-----------
1
3
6
8
2
21
34
35
26
40
How can I find the missing elements (4, 5, 7, 9, 10, etc.)?
SQL> create table bill (bill_id)
2 as
3 select 1 from dual union all
4 select 3 from dual union all
5 select 6 from dual union all
6 select 8 from dual union all
7 select 2 from dual union all
8 select 21 from dual union all
9 select 34 from dual union all
10 select 35 from dual union all
11 select 26 from dual union all
12 select 40 from dual
13 /
Table created.
SQL> with all_possible_bill_ids as
2 ( select level bill_id
3 from dual
4 connect by level <= 40
5 )
6 select bill_id
7 from all_possible_bill_ids
8 minus
9 select bill_id
10 from bill
11 /
BILL_ID
----------
4
5
7
9
10
11
12
13
14
15
16
17
18
19
20
22
23
24
25
27
28
29
30
31
32
33
36
37
38
39
30 rows selected.
Regards,
Rob.