Select max of count from a table and update another column - sql

I need to find the max value base on Count from column col1_class and update table2 column 'lbl1' with the value
I tried this code but i gets error:
update testClassLable
set lbl1 = (
select max(maxVal)
from (
select count (col1_class) as maxVal
from tbl_test_all
group by col1_class
)x
)
can you help please?
* UPDATE *
I edited the code above and its work now but it return :
0 row(s) affected !

try this
update testClassLable
set lbl1 = (
select max(countVal)
from (
select count(col1_class) as countVal
from tbl_test_all
group by col1_class
) x
)

Related

"ORA-00923: FROM keyword not found where expected\n what should I fix

I have an oracle query as follows but when I make changes to pagination the results are different. what should i pass for my code
SELECT *
FROM (
SELECT b.*,
ROWNUM r__
FROM (
select a.KODE_KLAIM,
a.NO_SS,
a.LA,
a.NAMA_TK,
a.KODE_K,
(
select tk.TEM_LAHIR
from KN.VW_KN_TK tk
where tk.KODE_K = a.KODE_K and rownum=1
) TEM_LAHIR,
(
select TO_CHAR(tk.TLAHIR, 'DD/MM/RRRR')
from KN.VW_KTK tk
where tk.KODE_K = a.KODE_K
and rownum=1
) TLAHIR
from PN.KLAIM a
where nvl(a.STATUS_BATAL,'X') = 'T'
and A.NOMOR IS NOT NULL
and A.TIPE_KLAIM = 'JPN01'
)b
)
where 1 = 1
WHERE ROWNUM < ( ( ? * ? ) + 1 )
WHERE r__ >= ( ( ( ? - 1 ) * ? ) + 1 )
but i run this query i have result ORA-00900: invalid SQL statement
You have three WHERE clauses at the end (and no ORDER BY clause). To make it syntactically valid you could change the second and third WHERE clauses to AND.
However, you mention pagination so what you probably want is to use:
SELECT *
FROM (
SELECT b.*,
ROWNUM r__
FROM (
select ...
from ...
ORDER BY something
)b
WHERE ROWNUM < :page_size * :page_number + 1
)
WHERE r__ >= ( :page_number - 1 ) * :page_size + 1
Note: You can replace the named bind variables with anonymous bind variables if you want.
Or, if you are using Oracle 12 or later then you can use the OFFSET x ROWS FETCH FIRST y ROWS ONLY syntax:
select ...
from ...
ORDER BY something
OFFSET (:page_number - 1) * :page_size ROWS
FETCH FIRST :page_size ROWS ONLY;
Additionally, you have several correlated sub-queries such as:
select tk.TEM_LAHIR
from KN.VW_KN_TK tk
where tk.KODE_K = a.KODE_K and rownum=1
This will find the first matching row that the SQL engine happens to read from the datafile and is effectively finding a random row. If you want a specific row then you need an ORDER BY clause and you need to filter using ROWNUM AFTER the ORDER BY clause has been applied.
From Oracle 12, the correlated sub-query would be:
select tk.TEM_LAHIR
from KN.VW_KN_TK tk
where tk.KODE_K = a.KODE_K
ORDER BY something
FETCH FIRST ROW ONLY

How do I UPDATE from a SELECT in Informix?

I'm trying to do an update using data from another table. I've tried this answer (the second part), but it is not working for me. I'm receiving a generic error message of syntax error.
I've also tried this solution and received a syntax error message too.
If I try to update just one column, it works:
UPDATE dogs
SET name =
(
SELECT 'Buddy'
FROM systables
WHERE tabid = 1
);
But I need to update multiples columns. Unfortunately, this is not working:
UPDATE dogs
SET (name, breed) =
(
SELECT 'Buddy', 'pug'
FROM systables
WHERE tabid = 1
);
Informix version is 12.10.FC8
You are missing 1 more set of parentheses around the subquery.
From the Informix manual:
The subquery must be enclosed between parentheses. These parentheses
are nested within the parentheses that immediately follow the equal (
= ) sign. If the expression list includes multiple subqueries, each subquery must be enclosed between parentheses, with a comma ( , )
separating successive subqueries:
UPDATE ... SET ... = ((subqueryA),(subqueryB), ... (subqueryN))
The following examples show the use of subqueries in the SET clause:
UPDATE items
SET (stock_num, manu_code, quantity) =
(
(
SELECT stock_num, manu_code
FROM stock
WHERE description = 'baseball'
),
2
)
WHERE item_num = 1 AND order_num = 1001;
UPDATE table1
SET (col1, col2, col3) =
(
(
SELECT MIN (ship_charge), MAX (ship_charge)
FROM orders
),
'07/01/2007'
)
WHERE col4 = 1001;
So in order for your update to be accepted by Informix it has to be:
UPDATE dogs
SET (name, breed) =
(
(
SELECT 'Buddy', 'pug'
FROM systables
WHERE tabid = 1
)
);

Update Oracle table based on nested select incl. package function

I have a query which calls a function in a package to create a percentage value as a sum of about 30 columns.
What I'd like to do is update each row based on the "sum of counted columns" as a percentage.
The select query is:
SELECT
checklist_id,
row_status,
eba_cm_checklist_std.get_row_percent_complete(pc.id,pc.checklist_id,pc.max_col_num) AS percent_complete
FROM
(
SELECT
(
SELECT
COUNT(id)
FROM
eba_cm_checklist_columns
WHERE
checklist_id = r.checklist_id
) AS max_col_num,
r.*
FROM
eba_cm_checklist_rows r
ORDER BY
r.row_order,
r.name
) pc
and the package.function that creates the percentage is "eba_cm_checklist_std.get_row_percent_complete".
The query outputs the following:
checklist_id row_status percent_complete
97176759931088640236098007249022291412 Red 0
97176759931071715274623402440576404948 Red 0
97176759931071715274623402440576404948 Red 0
97176759931071715274623402440576404948 Red 0
97176759931088640236098007249022291412 Red 0
97176759931088640236098007249022291412 Red 0
97176759931081386681180319473974054356 Grey 100
97176759931051163535689953744606399956 Grey 100
The difficulty I'm having is that the expression is using a nested select statement based on the output of a function and I can't get my head around how to update the physical "eba_cm_checklist_rows" table based on the output of the query.
Basically, I want to do the following:
update set row_status = 'Green' where percent_complete = 100
Another option is to use bulk select/update:
declare
type t_rid_arr is table of rowid index by pls_integer;
type t_row_status_arr is table of eba_cm_checklist_rows.row_status%type index by pls_integer;
type t_percent_complete_arr is table of number index by pls_integer;
l_rid_arr t_rid_arr;
l_row_status_arr t_row_status_arr;
l_percent_complete_arr t_percent_complete_arr;
begin
SELECT
rid,
row_status,
eba_cm_checklist_std.get_row_percent_complete(pc.id,pc.checklist_id,pc.max_col_num) AS percent_complete
bulk collect into
l_rid_arr,
l_row_status_arr,
l_percent_complete_arr
FROM (
SELECT r.rowid as rid,
r.*,
count(*) over(partition by checklist_id) AS max_col_num
FROM eba_cm_checklist_rows r
) pc;
forall i in 1..l_rid_arr.count
update eba_cm_checklist_rows
set row_status = case when l_percent_complete_arr(i) = 100 then 'Green' else row_status end
where rowid = l_rid_arr(i);
end;
/
you could try to use CTE and SUM() OVER() function, hope you find it useful.
Try something like this:
merge into eba_cm_checklist_rows trg
using (
SELECT
rid,
checklist_id,
row_status,
eba_cm_checklist_std.get_row_percent_complete(pc.id,pc.checklist_id,pc.max_col_num) AS percent_complete
FROM
(
SELECT r.rowid as rid,
r.*,
count(*) over(partition by checklist_id) AS max_col_num
FROM eba_cm_checklist_rows r
) pc
) src
on (trg.rowid = src.rid)
when matched then update set row_status = 'Green' where percent_complete = 100;
I don't like the idea to use function inside the SQL - it's probably could be replaced with normal SQL.

select specific records using IN

I need to select records that has ID = 10,23,30 so I wrote this SQL
Select * from mytable where position(id in '10,23,30') > 0
But the problem I get additional records where ID = 1 and 2
Any ideas how to select only what I need ?
No need for position, just do IN:
Select * from mytable
where id in (10,23,30)
Use IN operator:
Select * from mytable where id in (10,23,30)

return a default record from a sql query

I have a sql query that I run against a sql server database eg.
SELECT * FROM MyTable WHERE Id = 2
This may return a number of records or may return none. If it returns none, I would like to alter my sql query to return a default record, is this possible and if so, how? If records are returned, the default record should not be returned. I cannot update the data so will need to alter the sql query for this.
Another way (you would get an empty initial rowset returned);
SELECT * FROM MyTable WHERE Id = 2
IF (##ROWCOUNT = 0)
SELECT ...
SELECT TOP 1 * FROM (
SELECT ID,1 as Flag FROM MyTable WHERE Id = 2
UNION ALL
SELECT 1,2
) qry
ORDER BY qry.Flag ASC
You can have a look to this post. It is similar to what you are asking
Return a value if no rows are found SQL
I hope that it can guide you to the correct path.
if not exists (SELECT top 1 * FROM mytable WHERE id = 2)
select * from mytable where id= 'whatever_the_default_id_is'
else
select * from mytable where id = 2
If you have to return whole rows of data (and not just a single column) and you have to create a single SQL query then do this:
Left join actual table to defaults single-row table
select
coalesce(a.col1, d.col1) as col1,
coalesce(a.col2, d.col2) as col2,
...
from (
-- your defaults record
select
default1 as col1,
default2 as col2,
...) as d
left join actual as a
on ((1 = 1) /* or any actual table "where" conditions */)
The query need to return the same number of fields, so you shouldn't do a SELECT * FROM but a SELECT value FROM if you want to return a default value.
With that in mind
SELECT value FROM MyTable WHERE Id = 2
UNION
SELECT CASE (SELECT count(*) FROM MyTable WHERE Id = 2)
WHEN 0 THEN 'defaultvalue'
END