Laravel - randomly select n number of rows containing same value in certain column after applying 'order by' - laravel

In my Laravel project, in the database table ads, I have the following structure :
id | col1 | col2
col2 has values like topad, bump,urgent along with empty value. I want to take all the rows from the ads table and sort them alphabetically based on col2 in descending order.
So I used:
Ads::orderBy('col2','DESC')->get()
Now I have 2 conditions to be applied on the query.
1st condition : Suppose there are 4 rows with topad in col2, 5 rows with urgent in col2, 6 rows with bump in col2 and 7 rows each with an empty value in col2 . So rows with urgent in col2 will appear 1st, with topad in col2 will appear 2nd and with bump in col2 will appear 3rd and with empty values in col2 will appear 4th. Now I need to randomize the rows' order within each set. For example , rows with topad in col2 may have the ids 1,2,3,4. I want to randomize these rows (which may result into for example 4,2,1,3). But they will appear before rows containing topad in col2. Same is true for topad and bump row sets and rows containing any empty value in col2.
So the query becomes :
Ads::orderBy('col2','DESC')->inRandomOrder()->get();
2nd condition : Suppose rows are ordered by col2 values. But from each set of rows containing same value in col2, I need n number of rows from those that have non-empty value in col2 i.e. randomly I need n rows from urgented rows, n from topaded rows, n from bumped rows and all from emptyed rows.
How to write the query then ?

You could do this with subqueries, but in my experience they take more time to execute then a few smaller ones (if they are indexed correctly). Also, you have more control over the limits and debugging issues.
$top_ads = Ads::whereCol2('topad')->inRandomOrder()->limit(5)->get();
$urgent_ads = Ads::whereCol2('urgent')->inRandomOrder()->limit(10)->get();
$bump_ads = Ads::whereCol2('bump')->inRandomOrder()->limit(2)->get();
This will create your queries and after that you can do whatever you want with their collections. Combine them, reorder them, etc.

Related

How do I exclude certain columns within a transformation?

When using Upsolver SQLake, if my source table has 100's of columns, and I want to include most of them in a transformation, but exclude a few, can I do that without having to explicitly map every column in the transformation SQL?
For example, if my source table has 5 columns, (col1, col2, col3, col4, col5), and in my transformation I do not want to include col3. I could use the following SQL:
SELECT col1, col2, col4, col5 FROM sourcetable
However, if my source table has 1000 columns, I'd rather not have to type out 999 columns if I don't have to.
I was looking for an option to generate SQL, or some option to exclude certain columns from a transformation.
SQLake supports an EXCEPT parameter in the transformation job definition. The transformation SQL will be evaluated, however columns in the EXCEPT reference will be excluded in the target table.
CREATE JOB insert_all_columns_except_col3
START_FROM = NOW
ADD_MISSING_COLUMNS = TRUE
RUN_INTERVAL = 1 MINUTE
AS INSERT INTO target_table MAP_COLUMNS_BY_NAME EXCEPT col3
SELECT *
FROM source_table
WHERE $commit_time BETWEEN RUN_START_TIME() and RUN_END_TIME();
In this case, all columns from "source_table" will be written into "target_table" except for col3.

Oracle - insert only rows with column value which doesn't exist in table

I have two identical tables in Oracle (identical by structure) - table_temp and table_total.
I need to insert in table_total rows from table_temp based on following condition - only rows from table_temp with PLAYER_ID value which doesn't exist in table_total should be inserted in table_total.
Table_temp has 112 milions of records.
I tried many solutions but it took too long time to process so I stopped execution. This is my last try I stopped after 7 hours:
INSERT INTO table_total
SELECT *
FROM table_temp
WHERE table_temp.player_id NOT IN (SELECT player_id FROM table_total)
What is best/fastest solution for this? Indexing column is not acceptable solution...
Use a MERGE statement:
MERGE INTO table_total dst
USING table_temp src
ON (src.player_id = dst.player_id)
WHEN NOT MATCHED THEN
INSERT (player_id, col1, col2, col3)
VALUES (scr.player_id, src.col1, src.col2, src.col3);

Calculating difference between a row and its next row (same column) after sorting them based on the same column

How to calculate difference between a row and its next row (same column) after sorting them based on the same column.
select col_name - lead(col_name) over (order by col_name) from table_name
will do what you need. The result for the largest value in the column should be NULL (since there is no "next row" for that row).
If you also separate by another column, for example by employee_id, you need a partition clause as well, as in
...over (partition by employee_id order by column_name)...

Distinct Column in Hive

I am trying to get a query result in HiveQL with one column as distinct. However the results are not matching . There are almost 20 columns in the table.
create table uniq_us row format delimited fields terminated by ',' lines terminated by '\n' as select distinct(a),b,c,d,e,f,g,h,i,j from ctry_us_join;
The resulting number of Rows :513238
select count(distinct a) from ctry_us_join;
The resulting number of rows : 151616
How is this possible and is something wrong in my first or second query
U need to use subselect with group by statement.
select count(a) from (
select a, count(*) from ctry_us_join group by a) b
This is just one solution for this.
Distinct is a keyword, not a function. It applies to all columns you list in your select clause. It is quite reasonable that your table has only 151,616 distinct values in the column a, but multiple rows with the same value in the column a have different values in other columns. That might give you 513,238 distinct rows.

Oracle, how update statement works

Question 1
Can anyone tell me if there is any difference between following 2 update statements:
UPDATE TABA SET COL1 = '123', COL2 = '456' WHERE TABA.PK = 1
UPDATE TABA SET COL1 = '123' WHERE TABA.PK = 1
where the original value of COL2 = '456'
how does this affect the UNDO?
Question 2
What about if I update a record in table TABA using ROWTYPE like the following snippet.
how's the performance, and how does it affect the UNDO?
SampleRT TABA%rowtype
SELECT * INTO SampleRT FROM TABA WHERE PK = 1;
SampleRT.COL2 = '111';
UPDATE TABA SET ROW = SampleRT WHERE PK = SampleRT.PK;
thanks
Is your question 1 asking whether UNDO (and REDO) is generated when you're running an UPDATE against a row but not actually changing the value?
Something like?
update taba set col2='456' where col2='456';
If this is the question, then the answer is that even if you're updating a column to the same value then UNDO (and REDO) is generated.
(An exception is when you're updating a NULL column to NULL - this doesn't generate any REDO).
For Question 1:
The outcome of the two UPDATEs for rows in your table where PK=1 and COL2='456' is identical. (That is, each such row will have its COL1 value set to '123'.)
Note: there may be rows in your table with PK=1 and COL2 <> '456'. The outcome of the two statements for these rows will be different. Both statements will alter COL1, but only the first will alter the value in COL2, the second will leave it unchanged.
For question 1:
There can be a difference as triggers can fire depending on which columns are updated. Even if you are updating column_a to the same value, the trigger will fire.
The UNDO shouldn't be different as, if you expand or shrink the length of a variable length column (eg VARCHAR or NUMBER), all the rest of the bytes of the record need to be shuffled along too.
If the columns don't change size, then you MAY get a benefit in not specifying the column. You can probably test it using v$transaction queries to look at undo generated.
For question 2:
I'd be more concerned about memory (especially if you are bulk collecting SELECT * ) and triggers firing than UNDO.
If you don't need SELECT *, specify the columns (eg as follows)
cursor c_1 is select pk, col1, col2 from taba;
SampleRT c_1%rowtype;
SELECT pk, col1, col2 INTO SampleRT FROM TABA WHERE PK = 1;
SampleRT.COL2 = '111';
UPDATE (select pk, col1, col2 from taba)
SET ROW = SampleRT WHERE PK = SampleRT.PK;

Resources