Generate List for label with barcode printing from tablem with number quantity of rows - oracle

I try to generate list of products for printing labels, but all of my attempt fail (with connect by level)!
My table:
CREATE TABLE LABELS
(
PRODUCT VARCHAR2(8 BYTE),
Q_ROWS NUMBER
);
Information in the table:
INSERT INTO LABELS (PRODUCT, Q_ROWS) VALUES('D', 3);
INSERT INTO LABELS (PRODUCT, Q_ROWS) VALUES('A', 1);
INSERT INTO LABELS (PRODUCT, Q_ROWS) VALUES('C', 4);
INSERT INTO LABELS (PRODUCT, Q_ROWS) VALUES('B', 2);
Expected Result in a oracle select
PRODUCT
A
B
B
C
C
C
C
D
D
D
Results: (1 row for A, 2 rows for B, 4 rows to C and 3 rows to D)
Can someone help me?

Use LEVEL to get a "table" that counts from 1 to the maximum number of rows:
SELECT LEVEL AS LabelNum
FROM DUAL
CONNECT BY LEVEL <= (SELECT MAX(Q_Rows) FROM Labels)
This will give you the following table:
LabelNum
--------
1
2
3
4
Next, join this to your LABELS table where LabelNum <= Q_Rows. Here's the whole query:
WITH Mult AS (
SELECT LEVEL AS LabelNum
FROM DUAL
CONNECT BY LEVEL <= (SELECT MAX(Q_Rows) FROM Labels)
)
SELECT Product
FROM Labels
INNER JOIN Mult ON LabelNum <= Q_Rows
ORDER BY Product, LabelNum
There's a working SQLFiddle here.
Finally, good job including the create/populate scripts :)

Another approach, using model clause:
select product
from labels
model
partition by (product)
dimension by (1 as indx)
measures(q_rows)
rules(
q_rows[for indx from 1 to q_rows[1] increment 1] = q_rows[1]
)
order by product
result:
PRODUCT
----------
A
B
B
C
C
C
C
D
D
D
SQLFiddle Demo

Related

How to update data by select random row value from another table

I have three tables A, B, C, and I want to randomly take a row from the col_b column of the table B then update it to the table A. Table C is the subtable of Table B, which is used to filter the data of Table B.
Here is my sql statement:
update a a
set a.col_a_b =
(select t.col_b
from (select a1.col_a, b1.col_b, a1.rn_var
-- the number 6 is because I only have 6 rows of data,
-- and the real situation should be the total number of conditions in table b
from (select a0.col_a, TRUNC(dbms_random.value(1, 6)) rn_var
from a a0) a1
left join (select b.col_b, rownum rn
from b b
where exists (select 1
from c c
where b.id = c.col_b_id
and c.col_c = 'c1')) b1
on a1.rn_var = b1.rn) t
where t.col_a = a.col_a);
I found a strange phenomenon:
If I remove a1.rn_var (line from (select a1.col_a, b1.col_b, a1.rn_var), it doesn't work as my expected
On the basis of the above, if I replace exists with left join (or join), the result is the same
If I reomve both a1.rn_var and exists, it will work fine.
I know there may be a better way to implement it, but who can tell me why?
Update:
Actually, it is caused by this sql:
select a1.col_a, b1.col_b -- remove a1.rn_var
from (select a0.col_a, TRUNC(dbms_random.value(1, 6)) rn_var from a a0) a1
left join (select b.col_b, rownum rn
from b b
where exists (select 1
from c c
where b.id = c.col_b_id
and c.col_c = 'c1')) b1
on a1.rn_var = b1.rn
-- this is for better display of results
where a1.col_a = 'a1';
In the above sql, I may get multiple rows of data or column b1.col_b is empty, as shown below:
a1 b1
a1 b2
a1 b4
------------------------------------------------
a1 -- here is null
In addition, each value of column a1.col_a is the same, I mean, if value a1 has multiple rows, then value a2 (and so on) has the same result, like this:
a1 b2
a1 b4
a1 b5
a2 b2
a2 b4
a2 b5
...
You can use a random number and order by that random number to get random records.
I prefer using the following technique:
UPDATE A A
SET
A.COL_A_B = (
SELECT
COL_B
FROM
(
SELECT
COL_B,
TRUNC(DBMS_RANDOM.VALUE(1, COUNT(1) OVER())) RANDOM_NUMBER --GENERATES RANDOM NUMBER
FROM
(
SELECT DISTINCT
B.COL_B -- FETCHING DISTINCT RESULT
FROM
B B
-- EXISTS IS CONVERTED INTO JOIN
JOIN C C ON ( B.ID = C.COL_B_ID
AND C.COL_C = 'c1' )
)
ORDER BY
RANDOM_NUMBER -- ORDERING IS DONE BY RANDOM NUMBER
FETCH FIRST ROWS ONLY -- FETCHING ONLY FIRST ROW FROM ORDERED RECORDS
)
)
Cheers!!

Oracle: prioritizing results based on column’s value

I have a data-set in which there are duplicate IDs in the first column. I'm hoping to obtain a single row of data for each ID based on the second column's value. The data looks like so:
ID Info_Source Prior?
A 1 Y
A 3 N
A 2 Y
B 1 N
B 1 N
B 2 Y
C 2 N
C 3 Y
C 1 N
Specifically the criteria would call for prioritizing based on the second column's value (3 highest priority; then 1; and lastly 2): if the 'Info_Source' column has a value of 3, return that row; if there is no 3 in the second column for a given ID, look for a 1 and if found return that row; and finally if there is no 3 or 1 associated with the ID, search for 2 and return that row for the ID.
The desired results would be a single row for each ID, and the resulting data would be:
ID Info_Source Prior?
A 3 N
B 1 N
C 3 Y
row_number() over() usually solves these needs nicely and efficiently e.g.
select ID, Info_Source, Prior
from (
select ID, Info_Source, Prior
, row_number() over(partition by id order by Info_source DESC) as rn
)
where rn = 1
For prioritizing the second column's value (3 ; then 1, then 2) use a case expression to alter the raw value into an order that you need.
select ID, Info_Source, Prior
from (
select ID, Info_Source, Prior
, row_number() over(partition by id
order by case when Info_source = 3 then 3
when Infor_source = 1 then 2
else 1 end DESC) as rn
)
where rn = 1

How to speed up EDIT_DISTANCE and Insert Query?

---------------
MASTER TABLE
---------------
DATA_KEY NUMBER
TEXT VARCHAR2(2000)
ORDER_NO NUMBER
---------------
DETAIL TABLE
---------------
DATA_KEY NUMBER
SIMILAR_DATA_KEY NUMBER
DISTANCE_COUNT NUMBER
---------------
INSERT QUERY
---------------
INSERT INTO DETAIL
(
SELECT DATA_KEY, SIMILAR_DATA_KEY, DISTANCE_COUNT
FROM
(
SELECT A.DATA_KEY AS DATA_KEY, B.DATA_KEY AS SIMILAR_DATA_KEY,
UTL_MATCH.EDIT_DISTANCE(A.TEXT, B.TEXT) AS DISTANCE_COUNT
FROM
(SELECT DATA_KEY, TEXT, ORDER_NO FROM MASTER) A
INNER JOIN
(SELECT DATA_KEY, TEXT, ORDER_NO FROM MASTER) B
ON (A.ORDER_NO < B.ORDER_NO)
)
WHERE DISTANCE_COUNT <= 5
)
I need compare MASTER table TEXT field with other TEXT field.
indexes are not exist.
master table 90,000 rows.
ORDER_NO field is for avoid duplicated compare. (1 .. 90000)
=============================================================
A.ORDER_NO < B.ORDER_NO
------------------------------------------
1, 1 <- exclude
1, 2 <- join
1, 3 <- join
1, 4 <- join
..
2, 1 <- exclude
2, 2 <- exclude
2, 3 <- join
2, 4 <- join
...
3, 1 <- exclude
3, 2 <- exclude
3, 3 <- exclude
3, 4 <- join
1. NOT need compare 1 and 1
2. Need compare 1 and 2
3. NOT need compare 2 and 1 (because, duplicate 2.)
so, for decrease compare count...
=============================================================
Slow zone is (WHERE DISTANCE_COUNT <= 5) ?
Slow zone is comparing rows (90000*89999/2) ?
Query elapse time is 7 days.
6,000 rows inserted to DETAIL table.
How to speed up?
I'm sorry for poor English...

Inserting Data using join in Hive

Hi I have two Tables and after Join I want to Insert Data into Third Tables. Problem I am facing is I have to create multiple records based on the value of Join.
Table 1
A B
-------
1 X
2 y
3 x
Table 2
A C
-------
1 Y
2 N
3 Y
I need to join Table 1 and Table 2 on Column A and Based on value of Column C in Table 2 I need to insert Records in Table 3
Rule
If Column C value is 'Y' then insert 3 Records as 'Red','Green','Blue'
If Column C value is 'N then insert 2 records as 'White','Black'
So Result should be
Table 3
A D
-----------
1 Red
1 Green
1 Blue
2 White
2 Black
3 Red
3 Green
3 Blue
Can you let me know how to achieve this using hiveql ? Thanks
You can create a third table Color
Table Color
------------------
Flag Color
Y Red
Y Blue
Y Green
N White
N Black
Now you can join them easily
Select * from Table1 T1
JOIN Table2 T2
ON T1.A = T2.C
JOIN COLOR C
ON T2.C = C.Flag

Oracle: how to flash back a specific column?

How do I flash back a specific column for all rows in a table?
For example, given this table:
select * from t as of scn 1201789714628;
a b
- -
x 1
y 2
z 3
select * from t;
a b
- -
x 4
y 5
z 6
I can flash back a column in a specific row as follows:
update t set b = (select b from t as of scn 1201789714628 where a='x') where a='x';
select * from t;
a b
- -
x 1
y 5
z 6
but I can't figure out the syntax to set b to its previous value this for all rows.
update t t1 set b = (select b from t as of scn 1201789714628) t2 where t1.a = t2.a;
Error at Command Line:11 Column:60
SQL Error: ORA-00933: SQL command not properly ended
You may try this:
update t t1
set b = (select b from (select a, b from t as of scn 1201789714628) t2
where t1.a = t2.a);
P.S. I'd recommend to copy your snapshot in a temporary table if you're not going to update it right now (it can dissapear very soon).

Resources