randomly select elements from given array imported from database - random

$rr=mysql_query("SELECT id FROM personalinfoo");
while($ss=mysql_fetch_array($rr))
{
echo $ss[g];
echo "<br/>";
}
from above data from database i have to print any two data randomly!!

You can select the random ids directly from database instead of fetching all of them and select random ids. Change the SQL to
SELECT id FROM personalinfoo order by rand() limit 2

Related

Can I use FOR ALL ENTRIES with GROUP BY?

Currently the code looks something like this:
LOOP AT lt_orders ASSIGNING <fs_order>.
SELECT COUNT(*) AS cnt
FROM order_items
INTO <fs_order>-cnt
WHERE order_id = <fs_order>-order_id.
ENDLOOP.
It is the slowest part of the report. I want to speed it up.
How can I use FOR ALL ENTRIES with GROUP BY?
Check the documentation. You can't use GROUP BY. Maybe in this case, you could try selecting your items with FAE outside of the loop, then count them using a parallel cursor:
REPORT.
TYPES: BEGIN OF ty_result,
vbeln TYPE vbeln,
cnt TYPE i.
TYPES: END OF ty_result.
DATA: lt_headers TYPE SORTED TABLE OF ty_result WITH UNIQUE KEY vbeln,
lv_tabix TYPE sy-tabix VALUE 1.
"get the headers
SELECT vbeln FROM vbak UP TO 100 ROWS INTO CORRESPONDING FIELDS OF TABLE lt_headers.
"get corresponding items
SELECT vbeln, posnr FROM vbap FOR ALL ENTRIES IN #lt_headers
WHERE vbeln EQ #lt_headers-vbeln
ORDER BY vbeln, posnr
INTO TABLE #DATA(lt_items).
LOOP AT lt_headers ASSIGNING FIELD-SYMBOL(<h>).
LOOP AT lt_items FROM lv_tabix ASSIGNING FIELD-SYMBOL(<i>).
IF <i>-vbeln NE <h>-vbeln.
lv_tabix = sy-tabix.
EXIT.
ELSE.
<h>-cnt = <h>-cnt + 1.
ENDIF.
ENDLOOP.
ENDLOOP.
BREAK-POINT.
Or join header/item with a distinct count on the item id (whichever column that would be in your table).
You should be able to do something like
SELECT COUNT(order_item_id) AS cnt, order_id
FROM order_items
INTO CORRESPONDING FIELDS OF TABLE lt_count
GROUP BY order_id.
Assuming that order_item_id is a key in the order_items table. And assuming that lt_count has two fields: cnt of type int8 and order_id of same type as your other order_id fields
PS: then you can loop over lt_count and move the counts to lt_orders. Or the other way around. To speed up the loop, sort one of the tables and use READ ... BINARY SEARCH
I did with table KNB1 (customer master in company code), where we have customers, which are created in several company codes.
Please note, because of FOR ALL ENTRIES you have to SELECT the full key.
TYPES: BEGIN OF ty_knb1,
kunnr TYPE knb1-kunnr,
count TYPE i,
END OF ty_knb1.
TYPES: BEGIN OF ty_knb1_fae,
kunnr TYPE knb1-kunnr,
END OF ty_knb1_fae.
DATA: lt_knb1_fae TYPE STANDARD TABLE OF ty_knb1_fae.
DATA: lt_knb1 TYPE HASHED TABLE OF ty_knb1
WITH UNIQUE KEY kunnr.
DATA: ls_knb1 TYPE ty_knb1.
DATA: ls_knb1_db TYPE knb1.
START-OF-SELECTION.
lt_knb1_fae = VALUE #( ( kunnr = ... ) ). "add at least one customer which is created in several company codes
ls_knb1-count = 1.
SELECT kunnr bukrs
INTO CORRESPONDING FIELDS OF ls_knb1_db
FROM knb1
FOR ALL ENTRIES IN lt_knb1_fae
WHERE kunnr EQ lt_knb1_fae-kunnr.
ls_knb1-kunnr = ls_knb1_db-kunnr.
COLLECT ls_knb1 INTO lt_knb1.
ENDSELECT.
Create a range table for your lt_orders, like lt_orders_range.
Do select order_id, count( * ) where order_id in lt_orders_range.
If you think this is too much to create a range table, you will save a lot of performance by running just one select for all orders instead of single select for each order id.
Not directly, only through a CDS view
While all of the answers provide a faster solution than the one in the question, the fastest way is not mentioned.
If you have at least Netweaver 7.4, EHP 5 (and you should, it was released in 2014), you can use CDS views, even if you are not on HANA.
It still cannot be done directly, as OpenSQL does not allow FOR ALL ENTRIES with GROUP BY, and CDS views cannot handle FOR ALL ENTRIES. However, you can create one of each.
CDS:
#AbapCatalog.sqlViewName: 'zorder_i_fae'
DEFINE VIEW zorder_items_fae AS SELECT FROM order_items {
order_id,
count( * ) AS cnt,
}
GROUP BY order_id
OpenSQL:
SELECT *
FROM zorder_items_fae
INTO TABLE #DATA(lt_order_cnt)
FOR ALL ENTRIES IN #lt_orders
WHERE order_id = #lt_orders-order_id.
Speed
If lt_orders contains more than about 30% of all possible order_id values from table ORDER_ITEMS, the answer from iPirat is faster. (While using more memory, obviously)
However, if you need only a couple hunderd order_id values out of millions, this solution is about 10 times faster than any other answer, and 100 times faster than the original.

Understanding the behavior of dbms_random.value in where clause

I have a table with two columns(Using oracle 11g database) : Country, IndexNumber. Table contains 10 rows(10 different cities and with its unique index number.)
For example:
Country IndexNUmber
India 1
Australia 2
. .
. .
. .
. .
US 10
Now i want to fetch a random row from above table by generating random number using dbms_random.value(1,10). To achieve that i am using below query:
select * from tab_name where indexnumber = dbms_random.value(1,10);
I am not able to understand the output of this query as some time it is fetching one row, some time zero rows and some time more that one row.
Can someone please make me understand how oracle is evaluating this query.
Thanks
Ankit
Since dbms_random.value is a nondeterministic PL/SQL function, it will be called once for each row evaluated by the query.
The function might return 4 when evaluating the first row, then it might return 8 on the second row, etc.
To compare each row to a single random number, you can turn the function call into a scalar subquery, e.g.:
select * from tab_name where indexnumber = (select dbms_random.value(1,10) from dual);
Since the subquery is not correlated to the main query, Oracle will execute it only once (for the first row returned from the table) and remember the result for all subsequent rows. In particular, if a suitable index is on indexnumber the query will be able to use it more efficiently since it knows it is probing for a single value.
When you run your original query:
select * from tab_name where indexnumber = dbms_random.value(1,10);
it appears that the call to dbms_random is happening for each record's where clause. In other words, there is a chance that every record in your table might be returned if the random number chosen happen to match the index for every record. If you want to retrieve a single random record, then follow this pattern:
select *
from
( select * from tab_name order by DBMS_RANDOM.VALUE )
where rownum < 2;

How to add running ID in a single UPDATE statement (Oracle)

let's assume I have a table tab1 in my Oracle DB 12.1, which has a column record_id (type NUMBER) and many other columns, among them a column named exchg_id.
This record_id is always empty when a batch of new rows gets inserted into the table. What I need to do is to populate the record_id with values 1..N for all rows that satisfy a condition ...WHERE EXCHG_ID = 'something' and number of such rows is N. Of course I know how to do this procedurally (in a for-loop), but I'd like to know if there's an faster way using a single UPDATE statement. I imagine something like this:
UPDATE tab1 SET record_id = {1..N} WHERE exchg_id = 'something';
Many thanks for your help!
UPDATE: the order of the rows is not important, I need no specific ordering. I just need unique record_id's 1..N for any given exchg_id.
You could use rownum to set record_id to 1 to N :
UPDATE tab1 SET record_id = rownum WHERE exchg_id = 'something';
If you have some offset, say 10, then use rownum + 10

Oracle duplicate entries bases on Two columns

i need a query to get duplicate entries from table A on bases of two columns (Acol2 and Acol3) and Bcol3 from Table b where A.Acol4= B.Bcol2.
theefore two crequirements
1-select duplicats entries( on basis of columns Acol2 & Acol3) and Bcol3 from table A and table B
2- where A.Acol4= B.Bcol2
I am able to write query to get duplicate entries but unable to get bcol3 with condition 2.
create the join and then group by to find duplicates
SELECT a.acol2, a.acol3, b.bcol3
FROM a, b
WHERE a.acol4 = b.bcol2
GROUP BY a.acol2, a.acol3, b.bcol3
HAVING COUNT (*) > 1

SSRS - T-SQL - Concatenate multiple rows

I have T-SQL query that joins multiple tables. I am using that in SSRS as Dataset query. I am only selecting two columns, ID and Names. I have three records with same "ID" values but three different "Names" values. In SSRS, I am getting the first "Names" value and I need to concatonate all three values with same ID and have it in one cell on a table.
How would I go about doing that?
I am using lookup to combine cube + sql
Pulling ID straight from a table but using Case statement for Names to define alias.
You can accomplish this in TSQL either using PIVOT to get them as separate columns which you can then combine in the report cell, or you can use one of these concatenation methods to get all the names in one column.
For example, you can do this:
SELECT SomeTableA.Id,
STUFF(
(SELECT ',' + SomeTableB.Names AS [text()]
FROM SomeTable SomeTableB
WHERE SomeTableB.Id = SomeTableA.Id
FOR XML PATH('')), 1, 1, '' )
AS ConcatenatedNames
FROM SomeTable SomeTableA
INNER JOIN AnotherTable
ON SomeTableA.Id = AnotherTable.SomeId
...

Resources