RISC-V: How can I change this code into a full fibonacci sequence? - sequence

This is the code that was given to me and I am asked to modify it in order to the full Fibonacci sequence and get outputs for n = 10 and n = 18. I've tried adding ecalls between lines but I can't seem to figure it out.
.data
.word 2, 4, 6, 8
n: .word 10
.text
main:
add t0, x0, x0
addi t1, x0, 1
la t3, n
lw t3, 0(t3)
fib:
beq t3, x0, finish
add t2, t1, t0
mv t0, t1
mv t1, t2
addi t3, t3, -1
j fib
finish:
addi a0, x0, 1
addi a1, t0, 0
ecall # print integer ecall
addi a0, x0, 10
ecall # terminate ecall

Related

Merge two nested sets into rows

I'm given a nested set database which has the following reduced structure:
Bus its root table (B)
CL
CR
SL
SR
1
6
1
12
Compound table which represents levels of hierarchy with each level having different attributes (C)
Level 1 (C1)
CL
CR
SL
SR
C5
C6
1
6
1
12
NULL
test
Level 2 (C2a)
CL
CR
SL
SR
C5
C6
2
3
1
12
foo
NULL
and (C2b)
CL
CR
SL
SR
C5
C6
4
5
1
12
bar
NULL
Lastly S containing signals where S1 is it’s id.
S1
S2
2
0xFA
..
..
11
0x10
Then comes the tricky part:
I need to create a list of the 10 S table items with the complete path and hierarchical values up the tree.
So it would result in a list with values that look something like this
S
C
..
C
R
S2-values
C2a-values
..
C1-values
R
..
..
..
..
..
S11-values
C2a-values
..
C1-values
R
S2-values
C2b-values
..
C1-values
R
..
..
..
..
..
S11-values
C2b-values
..
C1-values
R
Any suggestion to loosen the knot in my brain is helpful.
What I tried so far is the following, which does not seem to work as it just crashes the machine:
select
*
from
signal s,
compound c
join (
select
bus.short_name,
cBase.dtype,
cBase.value,
cPdu.relative_bit_position,
cPdu.bit_length,
cPdu.left_signal,
cPdu.right_signal,
cSwp.switch_code
from
compound as cbase
left join compound as cPdu on
cPdu.dtype = 'P'
and cBase.left_compound < cPdu.left_compound
and cBase.right_compound > cPdu.right_compound
left join compound as cswp on
cSwp.dtype = 'SWP'
and cBase.left_compound < cSwp.left_compound
and cBase.right_compound > cSwp.right_compound
left join bus as bus on
bus.left_compound < cBase.left_compound
and bus.right_compound > cBase.right_compound
where
cBase.dType = 'CF') as res on s.id between res.left_signal and res.right_signal
In the above code I restricted the depth of the categories to 3 (cBase, cPdu, cSwp).
What I need is a generalized approach that can handle all depths.

Need single data from multiple similar DATA in database

I want to find out the data in showing in multiple entries like this
5 296 19 7 887 DAAS GAGO {"password":""} 2017-06-24 13:33:15 2017-06-23 13:33:09 9 10 fuel 4 1 N125XP DAAS Requested
5 296 19 7 887 DAAS GAGO {"password":""} 2017-06-24 13:33:15 2017-06-23 13:33:09 9 10 fuel 4 1 N125XP DAAS Requested
I want to see this data once how to do it ?
I am using this Sql Statement to do so :
SELECT t1.trip_id,
t1.server_trip_id,
t1.aircraft_id,
t2.flight_id,
t3.server_fid,
t3.dep,
t3.dest,
t3.service_provider,
t3.flight_name,
t3.sta,
t3.std,
t4.booking_id,
t5.server_booking_id,
t5.type,
t5.trip_number,
t5.company_id,
t5.user_id,
t5.aircraft_registration,
t5.icao,
t6.status
FROM trip t1
JOIN trip_flight t2 ON t2.trip_id = t1.trip_id
JOIN flight t3 ON t3.fid = t2.flight_id
JOIN trip_flight_booking t4 ON t4.flight_id = t2.flight_id
JOIN booking t5 ON t5.booking_id = t4.booking_id OR t5.booking_id != t4.booking_id
JOIN booking_status t6 ON t6.booking_id = t5.booking_id OR t6.booking_id != t5.booking_id
where t1.aircraft_id="19"
Are you sure your joins are correct... this seems to match any row;
t5.booking_id = t4.booking_id OR t5.booking_id != t4.booking_id
as you have = or != with the same values....
That said, you can use DISTINCT
SELECT DISTINCT t1.trip_id , t1.server_trip_id, t1.aircraft_id,
t2.flight_id,
t3.server_fid,t3.dep,t3.dest,t3.service_provider,t3.flight_name,t3.sta,t3.std,
t4.booking_id,
t5.server_booking_id,t5.type,t5.trip_number,t5.company_id,t5.user_id,t5.aircraft_registration,t5.icao,
t6.status
FROM trip t1
JOIN trip_flight t2 ON t2.trip_id = t1.trip_id
JOIN flight t3 ON t3.fid = t2.flight_id
JOIN trip_flight_booking t4 ON t4.flight_id = t2.flight_id
JOIN booking t5 ON t5.booking_id = t4.booking_id OR t5.booking_id != t4.booking_id
JOIN booking_status t6 ON t6.booking_id = t5.booking_id OR t6.booking_id != t5.booking_id
where t1.aircraft_id="19"

Modify and add new records to an Access database

We have a MS Access 2016 database. We queried the DB to find some parts in inventory. The first few rows of the query results are below. We have a primary key called DBID with a unique number for all of our records in the original table.
ORIGINAL QUERY:
SELECT [Slash Series Query].BRAND, [Slash Series Query].[PRODUCT ID], [Slash Series Query].[STOCK QUANTITY] FROM [Slash Series Query] WHERE ((([Slash Series Query].[PRODUCT ID]) Not Like "k"));
RESULTS:
Slash Straight Bore Query
BRAND PRODUCT ID
FAG 230/500 BMB H14C W33
SKF 230/500 CA C08 W509
ZKL 230/500 MW33
KOY 230/500 RW513 SOFY
KOY 230/500R W33 C3 FY
FAG 230/530 MBR50150H78CW209C
FAG 230/530 C3 H40AC
NSK 230/530CAM E4 C3 S11
FAG 230/600 BM C3 W33 T52BW
FAG 230/600 C08W503
SKF 230/600 CA C08 W509
FAG 239/530 MBH40.T52BW
FAG 239/530MB
SKF 248/530 CAMA/C3/W20
TOR 249/850 W33 W45 CW57 C2
We would like to insert a solution that adds a new record to the database with a “K” in the part number and also adds a “_(MOD)” to the end of the part number, in addition to the existing part number, so it would look like this:
(Brand = 3 letter manufacturer code, Product ID = part number)
Slash Tapered Bore Query
BRAND PRODUCT ID
FAG 230/500 K BMB H14C W33 (MOD)
SKF 230/500 K CA C08 W509 (MOD)
ZKL 230/500 K MW33 (MOD)
KOY 230/500 K RW513 SOFY (MOD)
KOY 230/500 K R W33 C3 FY (MOD)
FAG 230/530 K MBR50150H78CW209C (MOD)
FAG 230/530 K C3 H40AC (MOD)
NSK 230/530 K CAM E4 C3 S11 (MOD)
FAG 230/600 K BM C3 W33 T52BW (MOD)
FAG 230/600 K C08W503 (MOD)
SKF 230/600 K CA C08 W509 (MOD)
FAG 239/530 K MBH40.T52BW (MOD)
FAG 239/530 K MB (MOD)
SKF 248/530 K CAMA/C3/W20 (MOD)
TOR 249/850 K W33 W45 CW57 C2 (MOD)
What would be the most efficient way to accomplish this?
You could try the MS Access substring and concatenation operators:
SELECT S.BRAND,
Mid(S.[PRODUCT ID], 1, 7) & " K" & Mid(S.[PRODUCT ID], 8) & " (MOD)" as [PRODUCT ID],
S.[STOCK QUANTITY]
FROM [Slash Series Query] S WHERE (S.[PRODUCT ID] Not Like "k");
I've used the table alias instead of the whole table name to reduce the query's size.
EXPLANATION:
Mid(columnName, starting char position, [optional last character position])
returns that part of the column value from the starting char position to the last character position if specified(end of the string if not specified.)
"a" & "b" & "c" uses the MS access concatenation operator & and results in "abc"
If you just want to select the values:
SELECT ssq.BRAND, ssq.[PRODUCT ID], ssq.[STOCK QUANTITY],
("K" & ssq.[PART NUMBER] & " (MOD)") as [PRODUCT ID]
FROM [Slash Series Query] as ss1q
WHERE ssq.[PRODUCT ID] Not Like "k";
If you want to insert this into the database, then use INSERT . . . SELECT.

SQL join in the where statement

I am currently having to use two different queries to get back the results that I'm looking for. I have tried combining the two queries together, but that ends with me getting a large amount of extra(duplicates) data that I do not need. Below I have the working query listed.
SELECT p1.note as Itemcode,
order.ID as OrderNo,
piece1.ID As Piece1,
piece2.ID As Piece2,
i1.count as Unit,
unit.count as TotalUnits,
i1.rack as RackNo,
p1.EndDate as Piece1Finish,
p2.EndDate as Piece2Finish,
unit.group as BatchNo
FROM db.dbo.unit
JOIN db.dbo.order on order.entry_ID = unit.entry_ID
JOIN db.dbo.piece piece1 on piece1.ID_piece = unit.ID_piece_1
JOIN db.dbo.piece piece2 on piece2.ID_piece = unit.ID_piece_3
JOIN db.dbo.items i1 on i1.ID_unit = unit.ID_unit
JOIN db.dbo.items i2 on i2.ID_unit = unit.ID_unit
JOIN db.dbo.items i3 on i3.ID_unit = unit.ID_unit
JOIN db.dbo.items i4 on i4.ID_unit = unit.ID_unit
JOIN db.dbo.process p1 on p1.ID_process = i1.ID_process
JOIN db.dbo.process p2 on p2.ID_process = i2.ID_process
JOIN db.dbo.process p3 on p3.ID_process = i3.ID_process
JOIN db.dbo.process p4 on p4.ID_process = i4.ID_process
WHERE p1.note like '12A%'
and p1.ID_pieceorder = '1'
and p1.ID_job = '150'
and p2.ID_pieceorder = '3'
and p2.ID_job = '150'
and i1.count = i2.count
and i1.count = i3.count
and i1.count = i4.count
and i1.rack = i2.rack
and p1.note = p2.note
and i1.status = '1'
and i2.status = '1'
and p3.ID_pieceorder = '0'
and p4.ID_pieceorder = '2'
and p3.ID_job = '153'
and p4.ID_job = '151'
and i3.status = '0'
and i4.status = '0'
and order.status <> '4'
ORDER BY OrderNo
This query works fine. The second set of data I query to find adds the following information
SELECT ...(same as above)
FROM ...(same as above plus the following)
JOIN db.dbo.items i5 on i5.ID_unit = unit.ID_unit
JOIN db.dbo.items i6 on i6.ID_unit = unit.ID_unit
JOIN db.dbo.process p5 on p5.ID_process = i5.ID_process
JOIN db.dbo.process p6 on p6.ID_process = i6.ID_process
WHERE p1.note like '12B%'
and ... (same as above plus the following)...
and p5.ID_pieceorder = '1'
and p5.ID_job = '152'
and p6.ID_pieceorder = '3'
and p6.ID_job = '152'
and i5.status = '1'
and i6.status = '1'
and i1.count = i5.count
and i1.count = i6.count
When I try to make a combined query, the table joins of i5, i6, p5, and p6 produce a massive amount of duplicated results for p1.note like '12A%' due to it not needing the fields. Is there a method where I can initiate a join in the WHERE statement so that it will only use those two tables when p1.note like '12B%'? Something along the lines of
SELECT ....
FROM ....
WHERE (p1.note like '12A%'
or
(p1.note like '12B%'
and p5.ID_pieceorder = '1'
and p5.ID_job = '152'
and p6.ID_pieceorder = '3'
and p6.ID_job = '152'
and i5.status = '1'
and i6.status = '1'
and i1.count = i5.count
and i1.count = i6.count
(JOIN db.dbo.items i5 on i5.ID_unit = unit.ID_unit
JOIN db.dbo.items i6 on i6.ID_unit = unit.ID_unit
JOIN db.dbo.process p5 on p5.ID_process = i5.ID_process
JOIN db.dbo.process p6 on p6.ID_process = i6.ID_process)))
I know that the syntax above will not work, but I am looking for a method similar to that.
**EDIT FOR TABLE STRUCTURE requested by DRapp
I'm going to fill out the results I get with ID_unit 782327
-db.dbo.items-
-ID_item- -ID_process- -count- -status- -rack- -ID_unit-
628335 782328 1 0 25 782327
628336 782330 1 1 25 782327
628337 782331 1 1 25 782327
628338 782333 1 0 25 782327
628339 782335 1 1 25 782327
628340 782336 1 1 25 782327
628341 782337 1 0 25 782327
-db.dbo.process-
-ID_process- -ID_unit- -ID_pieceorder- -ID_job- -sequence-
782328 782327 0 50 1
782329 782327 1 5305 1
782330 782327 1 150 1
782331 782327 1 152 2
782332 782327 2 5408 2
782333 782327 2 151 1
782334 782327 3 5308 3
782335 782327 3 150 1
782336 782327 3 152 2
782337 782327 0 153 4
-db.dbo.unit-
-ID_unit- -status- -ID_piece_1- -ID_piece_2--ID_piece_3--ID_product-count
782327 2 5305 5408 5308 50 1
db.dbo.items contains a unique key for each "item" that goes into a part, it contains the corresponding process code, the "count" field, the "status" of each "item", the rack for each "item", and the unit ID of each "ITEM".
db.dbo.process contains the unique key for each "process", the ID_unit, ID_pieceorder, ID_job, and the sequence. Each unit starts with ID_pieceorder 0 which is establishing the product type, then ID_piece 1 for the first piece, etc..
db.dbo.unit contains the unique key for each "unit", the codes for all its pieces, the status of the unit, and count which is the number of units.
db.dbo.piece is a table with the master list of codes on it.
-ID_Piece- -Desc-
5305 14black
5408 14blue
150 Cut
The point of needing 6 processes is as follows
p1 & i1: Making sure the Piece is Piece 1, is process 150, and that process 150 is complete
p2 & i2: Making sure the piece is piece 2, is process 150, and that process 150 is complete
p3 & i3: Making sure it the completion process, 153, is not completed.
p4 & i4: making sure the connector process, 152, isn't completed(hasn't connected the two pieces).
p5 & i5: some pieces require extra work done, this checks and makes sure that process, 152, is completed on piece 1.
P6 & i6: The same as p5 & i5 but for piece 2.
if you don't want duplicates use a Union in between them, move you order by clause to the bottom of the second one. Make sure you select columns are in the same order in both statements.
select (your columns)
From (tables and joins)
where (your where)
UNION
select (your columns)
From (tables and joins)
where (your where)
order by
Per chatroom clarification, I have come up with the the following for you to start with and minimally adjust as needed.
SELECT
u.id_unit,
u.count as TotalUnits,
u.group as BatchNo,
p1.ID_PieceOrder as Piece1Order,
p1Cut.ID_Process as Piece1CutProcessID,
i1Cut.Count as Item1CutCount,
i1Cut.Status as Item1CutStatus,
p1Tamp.ID_PieceOrder as Piece1OrderTampered,
p1Tamp.ID_Process as Piece1TamperedProcessID,
i1Tamp.Count as Item1TamperedCount,
i1Tamp.Status as Item1TamperedStatus,
p2.ID_PieceOrder as Piece2Order,
p2Cut.ID_Process as Piece2CutProcessID,
i2Cut.Count as Item2CutCount,
i2Cut.Status as Item2CutStatus,
p2Tamp.ID_PieceOrder as Piece2OrderTampered,
p2Tamp.ID_Process as Piece2TamperedProcessID,
i2Tamp.Count as Item2TamperedCount,
i2Tamp.Status as Item2TamperedStatus,
pSpacer.ID_PieceOrder as SpacerPieceOrder,
iSpacer.Count as SpacerCount,
iSpacer.Status as SpacerStatus,
pSealed.ID_PieceOrder as SealedPieceOrder,
iSealed.Count as SealedCount,
iSealed.Status as SealedStatus
FROM
db.dbo.unit u
JOIN Process p1
ON u.ID_Unit = p1.ID_Unit
AND u.ID_Piece_1 = p1.ID_Job
JOIN Process p1Cut -- ALL PIECES MUST BE CUT first
ON p1.ID_Unit = p1Cut.ID_Unit
AND p1.ID_PieceOrder = p1Cut.ID_PieceOrder
AND p1Cut.ID_Job = 150
JOIN Items i1Cut
ON p1Cut.id_process = i1Cut.id_process
LEFT JOIN Process p1Tamp -- NOT ALL PIECES MUST BE TEMPERED
ON p1Cut.ID_Unit = p1Tamp.ID_Unit
AND p1Cut.ID_PieceOrder = p1Tamp.ID_PieceOrder
AND p1Tamp.ID_Job = 152
LEFT JOIN Items i1Tamp
ON p1Tamp.id_process = i1Tamp.id_process
JOIN Process p2
ON u.ID_Unit = p2.ID_Unit
AND u.ID_Piece_3 = p2.ID_Job
JOIN Process p2Cut -- ALL PIECES MUST BE CUT first
ON p2.ID_Unit = p2Cut.ID_Unit
AND p2.ID_PieceOrder = p2Cut.ID_PieceOrder
AND p2Cut.ID_Job = 150
JOIN Items i2Cut
ON p2Cut.id_process = i2Cut.id_process
LEFT JOIN Process p2Tamp -- NOT ALL PIECES MUST BE TEMPERED
ON p2Cut.ID_Unit = p2Tamp.ID_Unit
AND p2Cut.ID_PieceOrder = p2Tamp.ID_PieceOrder
AND p2Tamp.ID_Job = 152
LEFT JOIN Items i2Tamp
ON p2Tamp.id_process = i2Tamp.id_process
LEFT JOIN Process PSpacer
ON u.ID_Unit = PSpacer.ID_Unit
AND u.ID_Job = 151
LEFT JOIN Items ISpacer
ON PSpacer.ID_Process = ISpacer.ID_Process
LEFT JOIN Process PSealed
ON u.ID_Unit = PSealed.ID_Unit
AND u.ID_Job = 153
LEFT JOIN Items ISealed
ON PSealed.ID_Process = ISealed.ID_Process
WHERE
u.ID_Unit IN (782327, 782328, 782329 )
-- just a sample of 3 unit IDs to test concept of the revised query structure
I started at the unit table. From that, I am taking each piece down its respective path... First to get the piece, then from the piece, its CUT which will always be required. From the CUT to its ITEM status record which will always exist. From the CUT, I am then looking for a TAMPERED status for the same piece order. Since not all glass needs to be tampered, I have this as a LEFT-JOIN. I then LEFT-JOIN to the tampered's item record by the process id.
I do the same for the SECOND piece.
Then, a LEFT-JOIN to see IF there is a spacing required (can change to JOIN if spacer is ALWAYS required)
Finally, a LEFT-JOIN on the job completed entry. Again, don't know if all the entries are pre-filled in up-front for ALL stages of the process vs not.
Notice my alias name reference from P1 for the process for piece 1, then the p1Cut to i1Cut, to p1Tamp to i1Tamp. So now, instead of generic p1-p6, I have context to the process or item. Additionally, I just grabbed all the columns from the respective piece, cut, tampered, spacer and sealed steps with clear column names. If you don't want something you can always remove it, but with this, you SHOULD never get any duplicates per a single UNIT.
I did not add the join to the order or piece tables respectively. I don't know if piece is really needed unless you had other columns such as the P1.Name, but your table structure dump showed the description.
Since I did not add any other qualifiers, you should get the entire status of a single UNIT in one row. I would adjust the WHERE clause to pick a range of a few units you can test and confirm the context. THEN, adjust the where clause to look for your other criteria such as an item count = another or not, or piece within your '%a%' context or not. However, I THINK this will get you well on your way.
Something like this
LEFT JOIN db.dbo.process p1
on p1.ID_process = i1.ID_process
and p1.note like '12A%'
and p1.ID_pieceorder = '1'
and p1.ID_job = '150'
and p2.ID_pieceorder = '3'
and p2.ID_job = '150'
and i1.count = i2.count
and i1.count = i3.count
and i1.count = i4.count
and i1.rack = i2.rack
and p1.note = p2.note
and i1.status = '1'
and i2.status = '1'
and p3.ID_pieceorder = '0'
and p4.ID_pieceorder = '2'
and p3.ID_job = '153'
and p4.ID_job = '151'
LEFT JOIN db.dbo.items i5
on i5.ID_unit = unit.ID_unit
and p1.note like '12B%'
and i5.status = '1'

nested dependent sql question

I'm trying to implement a front end for a reporting solution which is security dependent. The user has 12 levels of nested criteria to select from, the value of each affects all of the values below.
So the criteria selection on the page (each is a dropdown) looks something like this:
Criteria 1
Criteria 2
...
Criteria 12
There is a Security table that holds the values that are available to each user which has the following structure:
EmployeeID | Criteria_1_valid_Value | C2_valid_Value | ... | C12_valid_Value
x0001 | c1 | c2 | ... | c12
and each Employee will have one or (many) more rows in this table. Think of it as a flattened tree, with Criteria1 as the root node.
Based on keys, changing Criteria 1 will affect the values that are visible in Criteria 2 through 12. In the same way, changing the value in Criteria 2 affects the values available in Criteria 3 through Criteria 12. At each level, there is an option to select 'All Values,' which is represented by a space internally, for lookups. So I need a representation in the lookup table/view which takes into account that there may be a space at one or many levels.
Where I'm struggling is with finding a way to build the lookup view/table for each Criteria field using sql without having to resort to hardcoding.
For example, to build the lookup for criteria 2 the sql might look like this:
select EmployeeID, Criteria1, Criteria2
from Security
Union
select EmployeeID, ' ', Criteria2
from Security
Union
select EmployeeID, Criteria1, ' '
from Security
UNION
select EmployeeID, ' ', ' '
from Security
And so on. Unfortunately, of course, with 12 levels, the last works out to 2^12 unions, which frankly smells.
I've tried building a table for each level in batch, committing after each, then using the previous table joined to the Security table to build the next with a single UNION in each, but I can't seem to get the joins to work properly with the spaces.
I don't know if I'm overthinking this or completely missing something, but I feel like there has to be a simpler solution.
EDIT: This is on Oracle and I'm working with an ERP product as the underlying technology.
EDIT2: Thanks for the input everyone. I got the joins eorking correctly using joins like in the example proc from #Alex Poole below:
and (v_Criteria_1 = ' ' or Criteria_1_valid_Value = v_Criteria_1)
I was missing the v_Criteria_1 = ' ' or.
So I've got the tables loaded correctly (enough) now. This is turning into a tuning/optimization exercise. I'm going to look at the proc from #Alex Poole and the artithmetic approach of #JD_55 which I think might be very quick.
If your security table structure is something like
Name Null? Type
----------------------------------------- -------- ----------------------------
EMPLOYEEID VARCHAR2(9)
CRITERIA_1_VALID_VALUE VARCHAR2(15)
CRITERIA_2_VALID_VALUE VARCHAR2(15)
CRITERIA_3_VALID_VALUE VARCHAR2(15)
with data
EMPLOYEEI CRITERIA_1_VALI CRITERIA_2_VALI CRITERIA_3_VALI
--------- --------------- --------------- ---------------
alex crit 1a crit 1a 2a crit 1a 2a 3a
alex crit 1a crit 1a 2b crit 1a 2b 3a
alex crit 1a crit 1a 2c crit 1a 2c 3a
alex crit 1a crit 1a 2c crit 1a 2c 3b
alex crit 1b crit 1b 2a crit 1b 2a 3a
alex crit 1b crit 1b 2b crit 1b 2b 3a
alex crit 1b crit 1b 2c crit 1b 2c 3a
alex crit 1c crit 1c 2a crit 1c 2a 3a
then does this give the result you need?
create or replace type t_crit_values as table of varchar2(15)
/
show errors
create or replace function get_criteria(v_EmployeeID in varchar2,
v_Level in number,
v_Criteria_1 in varchar2 default ' ',
v_Criteria_2 in varchar2 default ' ',
v_Criteria_3 in varchar2 default ' ')
return t_crit_values as
cursor c_values is
select distinct(case v_Level
when 1 then Criteria_1_valid_Value
when 2 then Criteria_2_valid_Value
when 3 then Criteria_3_valid_Value
end) value
from security
where EmployeeID = v_EmployeeID
and (v_Criteria_1 = ' ' or Criteria_1_valid_Value = v_Criteria_1)
and (v_Criteria_2 = ' ' or Criteria_2_valid_Value = v_Criteria_2)
and (v_Criteria_3 = ' ' or Criteria_3_valid_Value = v_Criteria_3);
l_crit_values t_crit_values;
i number;
begin
l_crit_values := t_crit_values();
for r_value in c_values loop
l_crit_values.EXTEND;
l_crit_values(l_crit_values.LAST) := r_value.value;
end loop;
return l_crit_values;
end;
/
show errors
Then call the function, each time passing in the level you need and the selected values from all higher levels (which may be ' '). Something like
// first level
select * from table(get_criteria('alex', 1));
COLUMN_VALUE
---------------
crit 1a
crit 1b
crit 1c
// second level with 'crit 1b' selected
select * from table(get_criteria('alex', 2, 'crit 1b'));
COLUMN_VALUE
---------------
crit 1b 2a
crit 1b 2b
crit 1b 2c
// second level with 'crit 1c' selected
select * from table(get_criteria('alex', 2, 'crit 1c'));
COLUMN_VALUE
---------------
crit 1c 2a
// third level with 'crit 1b' and 'crit 1b 2a' selected
select * from table(get_criteria('alex', 3, 'crit 1b', 'crit 1b 2a'));
COLUMN_VALUE
---------------
crit 1b 2a 3a
// third level with 'crit 1b' and 'all values' selected
select * from table(get_criteria('alex', 3, 'crit 1b', ' '));
COLUMN_VALUE
---------------
crit 1b 2a 3a
crit 1b 2b 3a
crit 1b 2c 3a
I've only gone to three levels for brevity but it would be easy to expand. Or have I not understood what you're trying to do?
Say there were only 3 criteria you want a table like this?
id c1 c2 c3
0 a b c
1 a b space
2 a space c
3 a space space
4 space b c
5 space b space
6 space space c
7 space space space
If you create such a table using sqlloader for example including an id column from 0 to 2^12 -1 , put spaces into all the criteria columns then you could update it using arithmetic:
update temp set c1 = (select criteria1 ...) where mod(id,2) < 1;
update temp set c2 = (select criteria2 ...) where mod(id,4) < 2;
update temp set c3 = (select criteria3 ...) where mod(id,8) < 4;
Does seem like a weird requirement.
Consider a series of left outer self join with each criteria item dependent on the values of the prior criteria. You can use the NVL() function to return spaces instead of nulls when the left join produces null results:
select a.employeeId,
nvl(c1.criteria_1, ' '),
nvl(c2.criteria_2, ' '),
nvl(c3.criteria_3, ' '),
nvl(c4.criteria_4, ' '),
nvl(c5.criteria_5, ' '),
nvl(c6.criteria_6, ' '),
nvl(c7.criteria_7, ' '),
nvl(c8.criteria_8, ' '),
nvl(c9.criteria_9, ' '),
nvl(c10.criteria_10, ' '),
nvl(c11.criteria_11, ' '),
nvl(c12.criteria_12, ' ')
from security as a,
left outer join security as c1
on (c1.employeeId = a.employeeId)
left outer join security as c2
on (c2.employeeId = a.employeeId and
c2.criteria_1 = a.criteria_1)
left outer join security as c3
on (c3.employeeId = a.employeeId and
c3.criteria_1 = a.criteria_1 and
c3.criteria_2 = a.criteria_2)
left outer join security as c4
on (c4.employeeId = a.employeeId and
c4.criteria_1 = a.criteria_1 and
c4.criteria_2 = a.criteria_2 and
c4.criteria_3 = a.criteria_3)
left outer join security as c5
on (c5.employeeId = a.employeeId and
c5.criteria_1 = c1.criteria_1 and
c5.criteria_2 = a.criteria_2 and
c5.criteria_3 = a.criteria_3 and
c5.criteria_4 = a.criteria_4)
left outer join security as c6
on (c6.employeeId = a.employeeId and
c6.criteria_1 = c1.criteria_1 and
c6.criteria_2 = a.criteria_2 and
c6.criteria_3 = a.criteria_3 and
c6.criteria_4 = a.criteria_4 and
c6.criteria_5 = a.criteria_5)
left outer join security as c7
on (c7.employeeId = a.employeeId and
c7.criteria_1 = c1.criteria_1 and
c7.criteria_2 = a.criteria_2 and
c7.criteria_3 = a.criteria_3 and
c7.criteria_4 = a.criteria_4 and
c7.criteria_5 = a.criteria_5 and
c7.criteria_6 = a.criteria_6)
left outer join security as c8
on (c8.employeeId = a.employeeId and
c8.criteria_1 = c1.criteria_1 and
c8.criteria_2 = a.criteria_2 and
c8.criteria_3 = a.criteria_3 and
c8.criteria_4 = a.criteria_4 and
c8.criteria_5 = a.criteria_5 and
c8.criteria_6 = a.criteria_6 and
c8.criteria_7 = a.criteria_7)
left outer join security as c9
on (c9.employeeId = a.employeeId and
c9.criteria_1 = c1.criteria_1 and
c9.criteria_2 = a.criteria_2 and
c9.criteria_3 = a.criteria_3 and
c9.criteria_4 = a.criteria_4 and
c9.criteria_5 = a.criteria_5 and
c9.criteria_6 = a.criteria_6 and
c9.criteria_7 = a.criteria_7 and
c9.criteria_8 = a.criteria_8)
left outer join security as c10
on (c10.employeeId = a.employeeId and
c10.criteria_1 = c1.criteria_1 and
c10.criteria_2 = a.criteria_2 and
c10.criteria_3 = a.criteria_3 and
c10.criteria_4 = a.criteria_4 and
c10.criteria_5 = a.criteria_5 and
c10.criteria_6 = a.criteria_6 and
c10.criteria_7 = a.criteria_7 and
c10.criteria_8 = a.criteria_8 and
c10.criteria_9 = a.criteria_9)
left outer join security as c11
on (c11.employeeId = a.employeeId and
c11.criteria_1 = c1.criteria_1 and
c11.criteria_2 = a.criteria_2 and
c11.criteria_3 = a.criteria_3 and
c11.criteria_4 = a.criteria_4 and
c11.criteria_5 = a.criteria_5 and
c11.criteria_6 = a.criteria_6 and
c11.criteria_7 = a.criteria_7 and
c11.criteria_8 = a.criteria_8 and
c11.criteria_9 = a.criteria_9 and
c11.criteria_10 = a.criteria_10)
left outer join security as c12
on (c12.employeeId = a.employeeId and
c12.criteria_1 = c1.criteria_1 and
c12.criteria_2 = a.criteria_2 and
c12.criteria_3 = a.criteria_3 and
c12.criteria_4 = a.criteria_4 and
c12.criteria_5 = a.criteria_5 and
c12.criteria_6 = a.criteria_6 and
c12.criteria_7 = a.criteria_7 and
c12.criteria_8 = a.criteria_8 and
c12.criteria_9 = a.criteria_9 and
c12.criteria_10 = a.criteria_10 and
c12.criteria_11 = a.criteria_11);
I don't fully understand your requirements, but I would have thought that the query for criteria2 would be:
select distinct Criteria2
from Security
where EmployeeID = :the_user
and Criteria1 = :Criteria1
if the user must enter Criteria1 before Criteria2, or
select distinct Criteria2
from Security
where EmployeeID = :the_user
and (:Criteria1 is null or Criteria1 = :Criteria1)
otherwise?
So in the end it did come down to a performance issue. I created a table that held the binary representation of 2^10 integers in reverse (litte-endian, if you will).
DECBIN:
decimal binary
0 0000000000
1 1000000000
2 0100000000
...
1023 1111111111
I then cartesian join this to the security table and decode each bit to get the correct value.
So the sql looks something like this:
SELECT DISTINCT
t.employeeID,
DECODE (SUBSTR (x.binary, 1, 1), 0, ' ', t.c1) AS crit1,
DECODE (SUBSTR (x.binary, 2, 1), 0, ' ', t.c2) AS crit2,
DECODE (SUBSTR (x.binary, 3, 1), 0, ' ', t.c3) AS crit3,
DECODE (SUBSTR (x.binary, 4, 1), 0, ' ', t.c4) AS crit4,
DECODE (SUBSTR (x.binary, 5, 1), 0, ' ', t.c5) AS crit5,
DECODE (SUBSTR (x.binary, 6, 1), 0, ' ', t.c6) AS crit6,
DECODE (SUBSTR (x.binary, 7, 1), 0, ' ', t.c7) AS crit7,
DECODE (SUBSTR (x.binary, 8, 1), 0, ' ', t.c8) AS crit8,
DECODE (SUBSTR (x.binary, 9, 1), 0, ' ', t.c9) AS crit9,
DECODE (SUBSTR (x.binary, 10, 1), 0, ' ', t.c10) AS crit10,
DECODE (SUBSTR (x.binary, 10, 1), 0, 'Choose All',t.c11) AS crit10Descr
FROM Security t, DECBIN x
WHERE TO_NUMBER (x.decimal) BETWEEN 0 AND POWER (2, 10) - 1
This is faster by a factor of 10. Thanks #JD_55 for getting me tho think about the problem in a new way.