I've got a sequence that needs to sort a list based off earliest year vs. latest year. Due to some unique values in the year element, it is making the sort a little more complicated. Is there any way to achieve the following?
let $dates := ('1982', '2019', '2095', 'pre-1982', 'post-2095')
return
for $date in $dates
order by $date
return $date
the dates element text is usually the year in the data, but outlier cases have a pre- or post- attached. Any way to achieve this minimally?
I am not sure if this is minimal, but it works:
let $dates := ('1982', '2019', '2095', 'pre-1982', 'post-2095')
return
for $date in $dates
let $year :=
if (fn:contains($date, "-"))
then fn:substring-after($date, "-")
else $date
let $prepost :=
if (fn:starts-with($date, "pre"))
then -1
else if (fn:starts-with($date, "post"))
then 1
else 0
order by $year, $prepost
return $date
Just FYI: Definitely not minimal, but I wanted to know what fn:sort does when a sequence is returned. Turns out it does the right thing.
xquery version "3.1";
declare variable $local:ascending := 1;
declare variable $local:descending := -1;
declare function local:sort-prefixed-years ($y, $order) {
if (fn:contains($y, "-"))
then (
let $p := fn:tokenize($y, "-")
let $m :=
switch($p[1])
case "pre" return -1 * $order
case "post" return 1 * $order
default return 0
return (xs:integer($p[2]) * $order, $m)
)
else (xs:integer($y) * $order, 0)
};
declare function local:sort-prefixed-years-ascending ($prefixed-year) {
local:sort-prefixed-years($prefixed-year, $local:ascending)
};
declare function local:sort-prefixed-years-descending ($prefixed-year) {
local:sort-prefixed-years($prefixed-year, $local:descending)
};
let $dates := ('1982', '2019', '2095', 'pre-1982', 'post-2095')
return sort($dates, (), local:sort-prefixed-years-descending#1)
I have this clobagg function:
create or replace type clobagg_type as object(
text clob,
static function ODCIAggregateInitialize(sctx in out clobagg_type
) return number,
member function ODCIAggregateIterate(self in out clobagg_type,
value in clob
) return number,
member function ODCIAggregateTerminate(self in clobagg_type,
returnvalue out clob,
flags in number
) return number,
member function ODCIAggregateMerge(self in out clobagg_type,
ctx2 in clobagg_type
) return number
);
/
create or replace type body clobagg_type is
static function ODCIAggregateInitialize(sctx in out clobagg_type
) return number is
begin
sctx := clobagg_type(null);
return ODCIConst.Success;
end;
member function ODCIAggregateIterate(self in out clobagg_type,
value in clob
) return number is
begin
self.text := self.text || value;
return ODCIConst.Success;
end;
member function ODCIAggregateTerminate(self in clobagg_type,
returnvalue out clob,
flags in number
) return number is
begin
returnValue := self.text;
return ODCIConst.Success;
end;
member function ODCIAggregateMerge(self in out clobagg_type,
ctx2 in clobagg_type
)return number is
begin
self.text := self.text || ctx2.text;
return ODCIConst.Success;
end;
end;
/
create or replace function clobagg(input clob) return clob
deterministic
parallel_enable
aggregate using clobagg_type;
/
But the problem is that I get data not in the right order. Can you help me and tell me how do achieve right order? I need clobagg function because listagg and other can return 4000 bytes and in my case it is not enough.
Here is the query:
CREATE TABLE GO_PRJ_SACHV7.TEST_STEPS1 (
test_case_id NUMBER(9,0),
activity CLOB
);
INSERT INTO GO_PRJ_SACHV7.TEST_STEPS(test_case_id, activity)
select test_case_id, clobagg(activity1)
from (
select
testschrit.testfall_id as test_case_id,
TESTSCHRITT_NR,
CHR(10) || 'h2.' || TESTSCHRITT_NR || ' ' ||
CAST(TESTSCHRITT_BEZEICHNUNG AS varchar(800)) || CHR(10) ||
CAST(TESTSCHRITT_BESCHREIBUNG AS varchar(800)) || CHR(10) ||
CAST(testschrit.TESTSCHRITT_BESCHREIBUNG AS varchar(800)) ||
'||AKTIVITÄT_NR' || '||AKTIVITÄT_KÜRZEL' || '||AKTIVITÄT_BESCHREIBUNG' ||
'||AKTIVITÄT_ERWARTETES_ERGEBNIS||' || CHR(10) ||
clobagg(
' |' || aktiv.AKTIVITÄT_NR || ' |' || aktiv.AKTIVITÄT_KÜRZEL || ' |' ||
aktiv.AKTIVITÄT_BESCHREIBUNG || ' |' ||
aktiv.AKTIVITÄT_ERWARTETES_ERGEBNIS || ' |' || CHR(10)
) as activity1
FROM
GO_PRJ_SACHV7.TESTFALLBESCHREIBUNG tfb,
GO_PRJ_SACHV7.TESTSCHRITTE testschrit,
GO_PRJ_SACHV7.AKTIVITÄTEN aktiv
WHERE testschrit.testfall_id = tfb.testfall_id(+)
AND testschrit.TESTSCHRITT_ID=aktiv.TESTSCHRITT_ID (+)
Group by
testschrit.testfall_id,
testschrit.testschritt_id,
testschrit.TESTSCHRITT_NR,
CAST(TESTSCHRITT_BEZEICHNUNG AS varchar(600)),
CAST(TESTSCHRITT_BESCHREIBUNG AS varchar(600))
order by testschrit.testfall_id, TESTSCHRITT_NR
)
group by test_case_id;
I try to add 'activity' column to the table in the right order. For this moment I can add this to the table but with random order. When I am trying order data by aktiv.AKTIVITÄT_NR I also have to add this field to my group by and this destroy my grouping.
You're missing an order by for the inner aggregate. You need to order before aggregating. You do that before the outer aggregate but not the inner one.
That is the most efficient way to perform a left outer join in LINQ if I must do the following...
Filter Table 2 by a beginning and ending date.
All rows in Table 1 must remain, even if the filtering of Table 2 returns no rows.
The result must be grouped so that the columns from Table 2 get summed.
For example (example code variable names changed for propietary reasons), supposed I have a database with two tables. Table 1 has a list of doors with a building code, door ID and current status (open or closed) - the building code and door ID are the primary key. Table 2 has a list of events for all doors (an event is an opening or closing) plus a timestamp. So the columns are building code, door ID, timestamp, opening, closing. Opening and closing are integers with a 1 in the column for the appropriate event. There is a foreign key relationship between the two tables on the building code and door ID.
For my query I need to return a list of all the unique doors with the current door status and a sum of all the opening and closing events for a selected time period. An entry must be returned for each door, even if no events occured during the selected time period.
Below is the best LINQ code I could come up with. It works, but it seems really inefficient and hard to understand. How would you make it more efficient and easier to understand?
var query =
from doors in Context.Doors
join fevents in
(
from events in db.Events
where events.TimeStamp >= date1 && events.TimeStamp <= date2
select new { events.BuildingCode, events.DoorID, events.TimeStamp, events.Opening, events.Closing }
)
on new { doors.BuildingCode, doors.DoorID } equals { fevents.BuildingCode, fevents.DoorID }
into g1
from c in g1.DefaultIfEmpty()
group c by new
{
doors.BuildingCode,
doors.DoorID,
doors.DoorStatus
} into g2
select new
{
BuildingCode = g2.Key.BuildingCode,
DoorID = g2.Key.DoorID,
Status = g2.Key.DoorStatus
NumOpenings = g2.Sum(i => (i == null ? 0 : i.Opening)),
NumClosings = g2.Sum(i => (i == null ? 0 : i.Closing))
};
I think this is slightly easier to read
var query =
from doors in Context.Doors
from c in db.Events
.Where(events => doors.BuildingCode == events.BuildingCode)
.Where(events => doors.DoorID == events.DoorID)
.Where(events => events.TimeStamp >= date1 && events.TimeStamp <= date2)
.Select(events => new { events.BuildingCode, events.DoorID, events.TimeStamp, events.Opening, events.Closing })
.DefaultIfEmpty()
group c by new
{
doors.BuildingCode,
doors.DoorID,
doors.DoorStatus
} into g2
select new
{
BuildingCode = g2.Key.BuildingCode,
DoorID = g2.Key.DoorID,
Status = g2.Key.DoorStatus
NumOpenings = g2.Sum(i => (i == null ? 0 : i.Opening)),
NumClosings = g2.Sum(i => (i == null ? 0 : i.Closing))
};
The answer from #adducci helped me come up with a slightly different solution that I think is even more readable, albeit possibly less efficient.
var query =
from doors in Context.Doors
from events in doors.Events
.Where(i => i.TimeStamp >= date1 && i.TimeStamp <= date2)
.DefaultIfEmpty()
group new { doors, events }
by doors into g
select new
{
BuildingCode = g.Key.BuildingCode,
DoorID = g.Key.DoorID,
Status = g.Key.DoorStatus,
NumOpenings = g.Sum(i => (i.events == null ? 0 : i.events.Opening)),
NumClosings = g.Sum(i => (i.events == null ? 0 : i.events.Closing))
};
Note that an alternative method for filtering by date would be directly in the summing function, as below, but this is much less efficient since all records would be retrieved from the database and then filtered locally.
...
//from events in doors.Events
// .Where(i => i.TimeStamp >= date1 && i.TimeStamp <= date2)
// .DefaultIfEmpty()
from events in doors.Events
.DefaultIfEmpty()
...
NumOpenings = g.Sum(i => (i.events == null ? 0 : (i.events.Timestamp >= date1 && i.events.TimeStamp <= date2) ? i.events.Opening : 0)),
NumClosings = g.Sum(i => (i.events == null ? 0 : (i.events.Timestamp >= date1 && i.events.TimeStamp <= date2) ? i.events.Closing : 0))
...
I'm trying to create a typical Housie/Bingo Game ticket in Asp.net 2.0 (VB). But, not being succeeded. Ticket contains 3 row with 9 columns. Total 27 blocks, and it must be only 15 should be fill outta those 27. and each column contains value like 1st column should be between 1-10 and 2nd must have random values between 11-20.. It doesn't matter how many blocks filled in each column.. 1 is must, no single column should be blank, all 9 columns must be filled, some have all 3 blocks filled, some have 1 with total of 15 blocks filled in whole ticket. with random numbers..
Guys here was the typical housie ticket specification.. Please help me out generating a ticket like this. I've tried but, not being that much succeeded, I get whole column blank and validating columns.. takes extra load on system. please find me the way to make it.
You need deterministic algorithm
First redefine your requirements:
Every column should have at least 1 number, so no column should be completely blank
First column should have numbers from 1..10, second 11..20, third 21..30 and so on to the ninth column having from 81..90
only 15 numbers needed to fill the ticket
Additional requirement: Every row should have 5 numbers
This is how I'd do it:
First select 9 randoms (to satisfy first requirement)
1..10 - one random number from this range
11..20 - one random number from this range
...
81..90 - one random number from this range
Prepare an array (selectNums) of numbers 1..90 and remove all selected in step 1
Loop
get a random number from the selectNums array
add it to your ticket and remove it from the selectNums aray
if selected number fills a column of three then remove all numbers from that range from the selectNums array.
Go back to step 1 in the loop
This algorithm will take you exactly 9 steps + 6 steps in the loop so it's deterministic which is better for the processor utilization. And it also fills your ticket with up to three numbers per column and not less than 1 (if I understood your requirements due too poor english in the question).
Yo when you select random numbers you always select a number between 0 and selectNums array length which will give you position in array where you have to take a number from.
Additonal functionality to create the actual ticket
Above steps will get you to a point where you will get exactly 15 numbers with at most 3 from the same ten numbers range. Fine. All you have to do now is to create your ticket.
define 3 variables: row1Count, row2Count and row3Count and set them all to 0.
Fill the ticket by starting from the fully filled columns (all three numbers):
Get the first full column and fill it up in the ticket while also incrementing all three variables by one.
Remove these numbers from the selectNums array.
Go back to step 2.1.
Fill the ticket with columns with two numbers:
Get the first two numbers column. Fill them in the ticket by using three possible permutations of filling them in (1&2, 2&3, 1&3). Fill the first pair using the first permutation, second one with the second and so on. Don't forget to increment corresponding row counter variables.
remove those two numbers from selectNums array
Go back to step 3.1.
Fill the ticket with single number columns (those that have just one number):
Get the first number from selectNums array and put it in the row with the smallest count and put in on the ticket in that particular row. When there are at least two rows with the same count, you can select whichever you prefer by either selecting one randomly or taking the first one (quickest).
Remove the number from selectNums array
Go back to 4.1.
This part should get you to fully filled ticket with all columns having at least one number and all rows containing exactly 5 numbers in total.
If smaller numbers are not allowed to be under larger ones, you can always add an additional step to this process and reorder numbers in those columns that have more than just one number in it.
One final observation
This solution has been simplified by using arrays and counters. You could of course create a complete object model that would be functionally rich and would provide you all the info you need. You could for instance have a Ticket and TicketColumn classes:
public class TicketColumn
{
public int Count { get; }
public int? FirstRowValue { get; set; }
public int? SecondRowValue { get; set; }
public int? ThirdRowValue { get; set; }
...
public void Reorder() { ... }
}
public class Ticket
{
public TicketColumn[] Columns
public int FirstRowCount { get; private set; }
public int SecondRowCount { get; private set; }
public int ThirdRowCount { get; private set; }
...
}
Or something similar. This is just an idea that this whole program would be better off in object oriented manner.
I have prepared a code for playing Housie with an arbitrary number of players. It informs whether anyone has won the game and terminates when someone has won the full house
The approach given to this problem goes like this;
I have prepared 10 lists. Each list has with 3 unique random numbers arranged in ascending order, ranging from 10 to 20, 20 to 30, ..., 80 to 90. Next, I have assigned the first number in 5 random lists to the top row, the second number in another 5 random lists to the middle row, and the third number in another 5 random lists to the bottom row. I have done this with the intention of not repeating the numbers, ensuring that only 5 numbers are printed on each row of the ticket, each column has it's number in an ascending order form top to bottom
I have used empty strings ' ' to be printed where there are no numbers to be printed and I have used the asterisk/star ' * ' mark to tell to the player that he/she has marked that number on that ticket!
Here's a sample ticket;
<player name>, your ticket is as follows:-
[' ' ' ' ' ' '33' ' ' '54' '66' '72' '83']
[' ' '12' '27' ' ' '45' '57' ' ' ' ' '88']
['8' '19' '29' ' ' '49' ' ' ' ' '75' ' ']
<player name>, do you want to mark?(Type 'Yes' or 'No'):
I have then asked whether the player wants to mark. Then I ensure that the player inputs an integer present in the ticket and which has also been called
It's looks like this(after marking);
The lucky number is 54!
<player name>, your ticket is as follows:-
[' ' ' ' ' ' '33' ' ' '54' '66' '72' '83']
[' ' '12' '27' ' ' '45' '57' ' ' ' ' '88']
['8' '19' '29' ' ' '49' ' ' ' ' '75' ' ']
<player name>, do you want to mark?(Type 'Yes' or 'No'): Yes
<player name>, type the number you want to mark: 54
<player name>, your ticket is as follows:-
[' ' ' ' ' ' '33' ' ' '*54' '66' '72' '83']
[' ' '12' '27' ' ' '45' '57' ' ' ' ' '88']
['8' '19' '29' ' ' '49' ' ' ' ' '75' ' ']
Notice that there is an asterisk mark beside the integer 54
It then asks whether the user wants to check if he/she has won!
The confirmatory message regarding the winners is as follows;
<player name>, do you want to check if you have won?(Type 'Yes' or 'No'): Yes
Sorry <player name>, you have not won!
Jaldi 5 Winner: None
Top row winner: None
Middle row winner: None
Bottom row winner: None
Full house winner: None
I have ensured that the numbers called don't get repeated(The main board is a list with numbers ranging from 1 to 90 and each time a number is called the sam random number is removed from the main board and while the player is given the opportunity to mark, the code ensures that the number is present in the player's ticket and the number is not present in the main board. If the player inputs a number which doesn't satisfy the above mentioned conditions, it keeps on asking until the player input a correct number
The speciality of this code is that it accepts arbitrary number of players. It initially asks you the number of players playing the game and then asks that many times the name of each individual player
Finally, the code automatically gets terminated when a player wins the full house
Here's the code I've prepared;
import random
import numpy as np
def list_of_ten(lower_limit, upper_limit):
yield list(str(number) for number in range(lower_limit, upper_limit))
def replace(numbers_list, row, collection):
for element in numbers_list:
if len(element) == 1:
collection[row][0] = element
elif int(element) == 90:
collection[row][-1] = element
else:
collection[row][int(element[0])] = element
def check_number(number, array):
row_counter = 0
column_counter = 0
for row in array:
if number in row:
for element in row:
if element == number:
return True, tuple((row_counter, column_counter))
column_counter += 1
row_counter += 1
else:
return False, None
def class_instantiation(player_count, class_to_create):
names_dict = dict()
counter = 0
while counter < int(player_count):
temporaray_input = input(f"Enter the name of the player{counter + 1}: ")
names_dict[temporaray_input.lower()] = class_to_create(temporaray_input)
counter += 1
return names_dict
def call_method(diction):
for tup in diction.items():
diction[tup[0]].display_ticket()
diction[tup[0]].mark()
def call_numeral(diction):
for tup in diction.items():
return diction[tup[0]].call_number()
class Player:
board = list(range(1, 91))
jaldi_5_winner = None
top_row_winner = None
middle_row_winner = None
bottom_row_winner = None
full_house_winner = None
def __init__(self, name):
self.name = name
self.full_list = list()
self.check_top = list()
self.check_middle = list()
self.check_bottom = list()
n1 = random.sample(next(list_of_ten( 1, 10)), 3)
n2 = random.sample(next(list_of_ten(10, 20)), 3)
n3 = random.sample(next(list_of_ten(20, 30)), 3)
n4 = random.sample(next(list_of_ten(30, 40)), 3)
n5 = random.sample(next(list_of_ten(40, 50)), 3)
n6 = random.sample(next(list_of_ten(50, 60)), 3)
n7 = random.sample(next(list_of_ten(60, 70)), 3)
n8 = random.sample(next(list_of_ten(70, 80)), 3)
n9 = random.sample(next(list_of_ten(80, 91)), 3)
n1.sort()
n2.sort()
n3.sort()
n4.sort()
n5.sort()
n6.sort()
n7.sort()
n8.sort()
n9.sort()
number_list = [n1, n2, n3, n4, n5, n6, n7, n8, n9]
self.ticket = np.array([[' '] * 9] * 3)
self.top_row = [element[0] for element in random.sample(number_list, 5)]
self.middle_row = [element[1] for element in random.sample(number_list, 5)]
self.bottom_row = [element[2] for element in random.sample(number_list, 5)]
replace(self.top_row, 0, self.ticket)
replace(self.middle_row, 1, self.ticket)
replace(self.bottom_row, 2, self.ticket)
def display_ticket(self):
print("\n\n" + f"{self.name}, your ticket is as follows:-" + "\n")
print(self.ticket[0])
print(self.ticket[1])
print(self.ticket[2])
def call_number(self):
print(f"The lucky number is {Player.board.pop(Player.board.index(random.choice(Player.board)))}!")
def mark(self):
mark_it = input("\n" + f"{self.name}, do you want to mark?(Type 'Yes' or 'No'): ")
while not mark_it.lower() == 'yes' and not mark_it.lower() == 'no':
mark_it = input("\n" + f"{self.name}, please type 'Yes' or 'No' only: ")
if mark_it.lower() == 'yes':
mark_number = input("\n" + f"{self.name}, type the number you want to mark: " + " ")
condition = check_number(mark_number, self.ticket)
while not condition[0] or int(mark_number) in Player.board:
mark_number = input("\n" + "Type a number present in your ticket which has also been called: ")
condition = check_number(mark_number, self.ticket)
if mark_number in self.ticket[0]:
self.check_top.append(mark_number)
self.full_list.append(mark_number)
elif mark_number in self.ticket[1]:
self.check_middle.append(mark_number)
self.full_list.append(mark_number)
else:
self.check_bottom.append(mark_number)
self.full_list.append(mark_number)
self.ticket[condition[1][0]][condition[1][1]] = "*" + mark_number
self.display_ticket()
winner_input = input("\n" + f"{self.name}, do you want to check if you have won?(Type 'Yes' or 'No'): ")
while not winner_input.lower() == 'yes' and not winner_input.lower() == 'no':
winner_input = input("\n" + f"{self.name}, please type 'Yes' or 'No' only: ")
if winner_input.lower() == 'yes':
if len(self.full_list) == 5 and Player.jaldi_5_winner == None:
print("\n" + f"{self.name}, you have won jaldi 5!" + "\n")
Player.jaldi_5_winner = self.name
elif len(self.full_list) == 15 and Player.full_house_winner == None:
print("\n" + f"Congratulations, {self.name}, you have won the game!" + "\n")
Player.full_house_winner = self.name
elif len(self.check_top) == 5 and Player.top_row_winner == None:
print("\n" + f"{self.name}, you have won the top row!" + "\n")
Player.top_row_winner = self.name
elif len(self.check_middle) == 5 and Player.middle_row_winner == None:
print("\n" + f"{self.name}, you have won the middle row!" + "\n")
Player.middle_row_winner = self.name
elif len(self.check_bottom) == 5 and Player.bottom_row_winner == None:
print("\n" + f"{self.name}, you have won the bottom row!" + "\n")
Player.bottom_row_winner = self.name
else:
print("\n" + f"Sorry {self.name}, you have not won!" + "\n")
print(f" Jaldi 5 Winner: {Player.jaldi_5_winner} ")
print(f" Top row winner: {Player.top_row_winner} ")
print(f"Middle row winner: {Player.middle_row_winner}")
print(f"Bottom row winner: {Player.bottom_row_winner}")
print(f"Full house winner: {Player.full_house_winner}")
no_of_players = input("How many players are going to play housie?: ")
players_dict = class_instantiation(no_of_players, Player)
while True:
if Player.full_house_winner != None:
break
else:
call_numeral(players_dict)
call_method(players_dict)
Hello might be a decade late but here is how I did it. It's in C#
using System;
namespace HelloWorld
{
class Program
{
public static void Main (String[] args)
{
for(int times=0;times<2;times++)
{
startGame();
Console.WriteLine("******************************************************************");
}
}
private static void startGame()
{
int[,] game = new int[3, 9];
int occupancyLimit = 15;
while (occupancyLimit > 0)
{
int i = getRandomNumber(3);
int j = getRandomNumber(9);
//Console.Write(i);
//Console.Write(j);
// Console.Write(game[i,j]+" ");
int data = validateAndReturnNumber(i, j, game);
if (data>0)
{
game[i, j] = data;
occupancyLimit--;
//Console.WriteLine(game[i,j]);
}
}
for (int i = 0; i < game.GetLength(0); i++)
{
for (int j = 0; j < game.GetLength(1); j++)
{
Console.Write(game[i,j] + "\t");
}
Console.WriteLine();
}
}
private static int validateAndReturnNumber(int i, int j, int[,] game)
{
//do not override existing elements in array
if (game[i,j] != 0)
{
return -1;
}
//column cannot have more then two elements
int columncounter = 0;
for(int c=0;c<3;c++)
{
if(game[c,j]!=0)
{
columncounter++;
}
}
if(columncounter>=2)
{
return -1;
}
/*
//rows cannot have more
then two cells filled in and
//rows cannot have more
then two empty cells
for(int columnIndex=0;columnIndex<=6;columnIndex++)
{
if(game[i,columnIndex+2]!=0)
{
return -1;
}
}
*/
// rows cannot have more then 5 elements
int rowcounter = 0;
for(int r=0;r<9;r++)
{
if(game[i,r]!=0)
{
rowcounter++;
}
}
//Applying, rows cannot have more then 5 elements
if(rowcounter>=5)
{
return -1;
}
//return getRandomNumberForColumn(j);
int data = 0;
Boolean isValueSet = false;
do
{
data = getRandomNumberForColumn(j);
isValueSet = isValueExistsInCol(game, i, j, data);
} while (isValueSet);
return data;
}
private static bool isValueExistsInCol(int[,] game, int i, int j, int data)
{
Boolean status = false;
for(int k=0;k<3;k++)
{
if(game[k,j]==data)
{
status = true;
break;
}
}
return status;
}
private static int getRandomNumberForColumn(int high)
{
if(high==0)
{
high = 10;
}
else
{
high=(high + 1) * 10;
}
int low = high - 9;
Random random = new Random();
return random.Next(high-low)+low;
}
private static int getRandomNumber(int max)
{
Random random = new Random();
int num=random.Next(max);
return (num);
}
}
}
$arr = new SplFixedArray(27);
for($m=1;$m<=100000;$m++)
{
in:
$final_array = array();
foreach ( $arr as $key => $val )
$final_array[ $key+1 ] = $val;
$elements_array=array();
foreach ( $arr as $key => $val )
$elements_array[ $key+1 ] = $val;
for($i=1;$i<=count($elements_array);$i++)
{
if($i==1 || $i==10 || $i==19 )
{
$elements_array[$i]=rand(1,9);
}
if($i==2 || $i==11 || $i==20 )
{
$elements_array[$i]=rand(10,19);
}
if($i==3 || $i==12 || $i==21 )
{
$elements_array[$i]=rand(20,29);
}
if($i==4 || $i==13 || $i==22 )
{
$elements_array[$i]=rand(30,39);
}
if($i==5 || $i==14 || $i==23 )
{
$elements_array[$i]=rand(40,49);
}
if($i==6 || $i==15 ||$i==24 )
{
$elements_array[$i]=rand(50,59);
}
if($i==7 || $i==16 ||$i==25 )
{
$elements_array[$i]=rand(60,69);
}
if($i==8 || $i==17 || $i==26 )
{
$elements_array[$i]=rand(70,79);
}
if($i==9 || $i==18 || $i==27)
{
$elements_array[$i]=rand(80,90);
}
}
for($k=1;$k<=5;$k++)
{
$index1=rand(1,9);
$final_array[$index1]=$elements_array[$index1];
}
$x1 = 0;
$ar1=[];
for($q=1;$q<=9;$q++)
{
if(isset($final_array[$q]))
{
$ar1[$x1]= $q;
$x1++;
}
}
loop:
if($x1 != 5)
{
$in1 =rand(1,9);
if(!in_array($in1, array_keys($ar1)))
{
$final_array[$in1]=$elements_array[$in1];
$ar[$x1]= $in1;
$x1++;
}
goto loop;
}
$z1=0;
for($q=1;$q<=9;$q++)
{
if(isset($final_array[$q]))
{
$ar1[$x1]= $q;
$z1++;
}
}
if($z1 != 5)
goto in;
for($l=1;$l<=5;$l++)
{
$index2=rand(10,18);
$final_array[$index2]=$elements_array[$index2];
}
$x2 = 0;
$ar2=[];
for($q=10;$q<=18;$q++)
{
if(isset($final_array[$q]))
{
$ar2[$x2]= $q;
$x2++;
}
}
loop2:
if($x2 != 5)
{
$in2 =rand(10,18);
if(!in_array($in2, array_keys($ar2)))
{
$final_array[$in2]=$elements_array[$in2];
$ar[$x2]= $in2;
$x2++;
}
goto loop2;
}
$z2=0;
for($q=10;$q<=18;$q++)
{
if(isset($final_array[$q]))
{
$ar1[$x1]= $q;
$z2++;
}
}
if($z2 != 5)
goto in;
for($n=1;$n<=5;$n++)
{
$index3=rand(19,27);
$final_array[$index3]=$elements_array[$index3];
}
$x3 = 0;
$ar3=[];
for($q=19;$q<=27;$q++)
{
if(isset($final_array[$q]))
{
$ar3[$x3]= $q;
$x3++;
}
}
loop3:
if($x3 != 5)
{
$in3 =rand(19,27);
if(!in_array($in3, array_keys($ar3)))
{
$final_array[$in3]=$elements_array[$in3];
$ar[$x3]= $in3;
$x3++;
}
goto loop3;
}
$z3=0;
for($q=19;$q<=27;$q++)
{
if(isset($final_array[$q]))
{
$ar3[$x3]= $q;
$z3++;
}
}
if($z3 != 5)
goto in;
DB::table('tambola')->insert(['a1'=>$final_array[1],
'a2'=>$final_array[2],
'a3'=>$final_array[3],
'a4'=>$final_array[4],
'a5'=>$final_array[5],
'a6'=>$final_array[6],
'a7'=>$final_array[7],
'a8'=>$final_array[8],
'a9'=>$final_array[9],
'b1'=>$final_array[10],
'b2'=>$final_array[11],
'b3'=>$final_array[12],
'b4'=>$final_array[13],
'b5'=>$final_array[14],
'b6'=>$final_array[15],
'b7'=>$final_array[16],
'b8'=>$final_array[17],
'b9'=>$final_array[18],
'c1'=>$final_array[19],
'c2'=>$final_array[20],
'c3'=>$final_array[21],
'c4'=>$final_array[22],
'c5'=>$final_array[23],
'c6'=>$final_array[24],
'c7'=>$final_array[25],
'c8'=>$final_array[26],
'c9'=>$final_array[27],
]);
}
I want to search some keyword in table but I don't know to which column it is belonging to. I have got one of query for that as follows:
variable val varchar2(10)
exec :val := 'KING'
PL/SQL procedure successfully completed.
SELECT DISTINCT SUBSTR (:val, 1, 11) "Searchword",
SUBSTR (table_name, 1, 14) "Table",
SUBSTR (column_name, 1, 14) "Column" FROM cols,
TABLE (xmlsequence (dbms_xmlgen.getxmltype ('select '
|| column_name
|| ' from '
|| table_name
|| ' where upper('
|| column_name
|| ') like upper(''%'
|| :val
|| '%'')' ).extract ('ROWSET/ROW/*') ) ) t
ORDER BY "Table"
Searchword Table Column
KING EMP ENAME
but I am not getting appropriate output.I only got output as:
PL/SQL procedure successfully completed. I have tried but I didn't get satisfactory answer. Can anybody please help..?
The easiest query I can write for such scope is something like:
SELECT *
FROM <table>
WHERE UPPER(column1) LIKE UPPER('%' || :val || '%')
OR UPPER(column2) LIKE UPPER('%' || :val || '%')
OR UPPER(column3) LIKE UPPER('%' || :val || '%')
OR UPPER(column4) LIKE UPPER('%' || :val || '%');
In this query I search for value :val in all columns of the table using OR conditions, so if at least one column contains the value the row is fetched
If you have many columns you can write a query that builds the final query for you, like the following:
SELECT 'SELECT * FROM <table> WHERE ' || LISTAGG(column_name || ' LIKE ''%' || :val || '%''', ' OR ') WITHIN GROUP (ORDER BY column_name)
FROM dba_tab_columns
WHERE table_name = '<table>'
The result of this query is the query to execute. Note that Oracle has a limit of 4000 characters for a string field built in a query. If your where condition is too big the query will fail.
In this case, the only alternative is to write a stored procedure that builds the query and returns it in a CLOB variable, here's an example:
CREATE OR REPLACE FUNCTION build_query(in_table_name IN VARCHAR2, in_search IN VARCHAR2) RETURN `CLOB` IS
lc_query CLOB := 'SELECT * FROM ' || in_table_name || ' WHERE 1=0';
BEGIN
FOR c IN (
SELECT *
FROM user_tab_columns
WHERE table_name = in_table_name
ORDER BY column_name
) LOOP
lc_query := lc_query || ' OR ' || c.column_name || ' LIKE ''%' || in_search || '%''';
END LOOP;
RETURN lc_query;
END;
This function will works and generates strings longer than 4000 characters.