I have a table which name is product barcode and i want to return one column by using executescalar .I dont want to return datatable.Nevertheless my query returs rows .I just need barcode. Please help !!
I can figure out the problem by using recursive select loop but ı want to solve this problem by using partition by .
select BARCODE
,PRODUCT_BARCODE_TYPE_CODE
, ROW_NUMBER() over(partition by PRODUCT_NO order by PRODUCT_BARCODE_TYPE_CODE desc )
from PRODUCT_BARCODE
where PRODUCT_NO='111333666';
I expect output like this:
25000111133335555
it will return barcode like this. Query execution
If you only want the barcode from the row with the highest product_barcode_type_code for the specified product then you can do it without a subquery or explicit ranking function using last:
select max(barcode) keep (dense_rank last order by product_barcode_type_code) as barcode
from product_barcode
where product_no = 111333666;
You can include a partition by clause but there's no point as you're filtering on a single product_no anyway.
Very quick demo:
-- CTE for sample data
with product_barcode (product_no, product_barcode_type_code, barcode) as (
select 111333666, 1, 1234 from dual
union all select 111333666, 2, 2345 from dual
union all select 111333666, 3, 25000111133335555 from dual
)
select max(barcode) keep (dense_rank last order by product_barcode_type_code) as barcode
from product_barcode
where product_no = 111333666;
BARCODE
-----------------
25000111133335555
(I've assumed your product_no, at least, is a number type rather than a string, and thus omitted the single quotes you had around the literal value you're searching for; but if it is actually a string then include those of course..)
Select BARCODE + PRODUCT_BARCODE_TYPE_CODE + partBarCode
FROM
(
select BARCODE
,PRODUCT_BARCODE_TYPE_CODE
, ROW_NUMBER() over(partition by PRODUCT_NO order by
PRODUCT_BARCODE_TYPE_CODE desc ) as partBarCode
from PRODUCT_BARCODE
where PRODUCT_NO='111333666'
) as res
This assumes that all fields are of the same type Nvarchar() else they will be summarized as per integer.
Select to_char (BARCODE ) || to_char( PRODUCT_BARCODE_TYPE_CODE) from (
select BARCODE
,PRODUCT_BARCODE_TYPE_CODE
, ROW_NUMBER() over(partition by PRODUCT_NO order by PRODUCT_BARCODE_TYPE_CODE desc ) rn
from PRODUCT_BARCODE
where PRODUCT_NO='111333666'
)
Where rn = 1;
You can try below -
select concat(BARCODE,PRODUCT_BARCODE_TYPE_CODE) as barcode from
(
select BARCODE
,PRODUCT_BARCODE_TYPE_CODE
, ROW_NUMBER() over(partition by PRODUCT_NO order by PRODUCT_BARCODE_TYPE_CODE desc ) as rn
from PRODUCT_BARCODE
where PRODUCT_NO='111333666'
)A where rn=1
Related
I have a table in BigQuery which looks like this:
The sequence field is a repeated RECORD. I want to select one row per stepName but if there are multiple rows per step name, I want to choose the one where sequence.step.elapsedSeconds and sequence.step.elapsedMinutes are not null, otherwise select the rows where these columns are null.
As shown in the image above, I want to select row no. 2, 4 and 5. I have calculated ROW_NUMBER like this: ROW_NUMBER() OVER(PARTITION BY step.stepName) AS RowNum.
Here´s my query so far in trying to filter out the unwanted rows:
WITH DistinctRows AS
(
select timestamp,
ARRAY (
SELECT
STRUCT(
STRUCT(
step.elapsedSeconds,
step.elapsedMinutes,
) as step
)
FROM
UNNEST(source_table.sequence) AS sequence
) AS sequence,
ROW_NUMBER() OVER(PARTITION BY step.stepName) AS RowNum
from source_table,
unnest(sequence) as previousCalls
order by timestamp asc
)
SELECT *
FROM DistinctRows,
unnest(sequence) as sequence
where (rowNum = 1 and (step.elapsedSeconds is null and step.elapsedMinutes is null)
or (RowNum > 1 and step.elapsedSeconds is not null and step.elapsedSeconds is not null)
order by timestamp asc
I need help in figuring out how to filter out the rows like no. 1 and 3 and would appreciate some help.
Thanks in advance.
Hmmm . . . Assuming that stepname is not part of the repeated column:
SELECT dr.* EXCEPT (sequence),
(SELECT seq
FROM unnest(dr.sequence) seq
ORDER BY seq.step.elapsedSeconds DESC NULLS LAST,
sequence.step.elapsedMinutes DESC NULLS LAST
) as sequence
FROM DistinctRows dr
ORDER BY timestamp asc;
If stepname is part of sequence, then the subquery would reaggregate:
SELECT dr.* EXCEPT (sequence),
(SELECT ARRAY_AGG(sequence ORDER BY stepName)
FROM (SELECT seq,
ROW_NUMBER() OVER (PARTITION BY seq.stepName
ORDER BY seq.step.elapsedSeconds DESC NULLS LAST, sequence.step.elapsedMinutes DESC NULLS
) as seqnum
FROM unnest(dr.sequence) seq
) s
WHERE seqnum = 1
) as sequence
FROM DistinctRows dr
ORDER BY timestamp asc
I need to select from table by using group by clause and then order by clause
select id,EXID,Rate,Date,Currency from tb_exchange where Boolean='True' group by id,EXID,Rate,Date,Currency ORDER BY id DESC
But it return normally like
select * from tb_exchange where Boolean='True' ORDER BY id DESC
I need to return the newest item first and it groups by currency name. My Currency Name are (THB and USD )
Please help me,
thank in advance.
You may try using ROW_NUMBER here:
SELECT id, EXID, Rate, Date, Currency
FROM
(
SELECT *, ROW_NUMBER() OVER (PARTITION BY Currency ORDER BY Date DESC) rn
FROM tb_exchange
WHERE Boolean = 'True'
) t
WHERE rn = 1
ORDER BY id DESC;
This answer assumes that you want the latest record from each Currency group and that the Date column records how recent or old a given record is.
I have the following query:
WITH lftno(counterrow) AS (
VALUES(select rownos
from test.table1
where year='2020' and usage='1')
)
UPDATE test.deltable
SET year=concat('31.12.','2012')
WHERE ID IN (
select res.id
from (
select res.id
from (
SELECT ROW_NUMBER() OVER (ORDER BY year ASC) AS delyear
, ID, year
from test.deltable
) res
where year(res.year)='2012'
fetch first integer(counterrow) rows only
)
The result of the with select is 10 so I want the fetch first line to use that 10 as the value for the rows to catch.
The final query is a lot longer but to show the problem this is easy for readablity.
I tried
'fetch first ' || integer(counterrow) || ' rows only'
or as part of the where clause
AND row_number() over() <= counterrow
but that didn't work either.
The point is that I can not resort them with an over part. I just need the lines as given by the counterrow.
Any ideas?
Thanks for you help.
You can't use row_number() in a WHERE clause. And, the FETCH clause requires constants. But, you can use the row_number() in a subquery and use the result in the outer query. If I understand correctly, you want:
WITH lftno(counterrow) AS (
VALUES(select rownos from test.table1 where year = '2020' and usage = '1')
)
select res.id
from (SELECT ROW_NUMBER() OVER (ORDER BY year ASC) AS delyear,
ID, year
from test.deltable
) res
where year(res.year) = '2012' and
delyear <= counterrow;
My query looks like this:
with T1 as (
Select
Dept_No,
Product_No,
Order_No,
Order_Type
Row_number() over (partition by Product_ID order by Order_No desc) as "COUNT"
From Orders_Table)
Select * from T1
where ("COUNT" = '1' and "Order_Type" <> 'Cancel')
or ("COUNT" = '2' AND "Order_Type" <> 'Cancel'
So I'm trying to pull the most recent order that was not canceled. Essentially my ROW_number() over (partition by...) function labels the orders in sequential order with 1 being the most recent order and 2 being the second most recent order. The issue is that with this query it pulls both the most recent, and 2nd most recent order. I am trying to write this to where if it only gives one or the other. So if COUNT = 1 and the order_type is not cancel, only show me that record. If not then show me the 2nd.
Thanks so much for the help in advance. This is being done in Toad for Oracle 9.5 using SQL tab.
But you have an or.
If both or are satisfied you will get two rows.
with T1 as (
Select
Dept_No,
Product_No,
Order_No,
Order_Type
Row_number() over (partition by Product_ID order by Order_No desc) as "COUNT"
From Orders_Table
where "Order_Type" <> 'Cancel')
Select * from T1
where "COUNT" = '1'
Use a case expression to control which rows get a result from row_number(), here we avoid numbering any rows that have been cancelled:
WITH t1 AS (
SELECT
Dept_No
, Product_No
, Order_No
, Order_Type
/* the most recent order that was not canceled */
, case when order_type <> 'Cancel'
then ROW_NUMBER() OVER (PARTITION BY Product_ID
ORDER BY Order_No DESC)
end AS is_recent
FROM Orders_Table
)
SELECT
*
FROM t1
WHERE is_recent = 1
Or, perhaps the easiest way is to simply exclude cancelled orders e.g.
WITH t1 AS (
SELECT
Dept_No
, Product_No
, Order_No
, Order_Type
, ROW_NUMBER() OVER (PARTITION BY Product_ID
ORDER BY Order_No DESC)
AS is_recent
FROM Orders_Table
WHERE order_type <> 'Cancel'
)
SELECT
*
FROM t1
WHERE is_recent = 1
nb: row_number() returns an integer, so don't compare that column to a string
I have to get the row with longest string value for same id fields.
create table test(
id number,
test_data varchar2(20)
);
insert all
into test values (1,'aaa')
into test values (1,'a')
into test values (1,'abxw')
into test values (2,'aaa')
into test values (2,'tris')
select * from dual;
my desired output is
1 abxw --longest string
2 tris
how can I get the required output?? I am not getting any idea.
guys what about using cursor. can we use cursor for this purpose?? Does anyone have any idea? Is it possible??
Thank You.
I like using partition for these kind of queries:
select id,test_data from (
select
id, test_data,
row_number() over( partition by id order by length(test_data) desc) as rnum
from
test
) where rnum=1
http://www.sqlfiddle.com/#!4/66d4c/20
Of course, the nice thing about this is that if you decide that you want another tiebreak (e.g., alphabetically), you just need to add that to your order by clause. Which, by the way is not a bad idea, that way your result set will not be non-deterministic.
You can try this query. It will return multiple results if multiple strings have the longest length per id:
select
t1.id, t1.test_data
from
test t1
join
(select id, max(length(test_data)) as len from test group by id) t2
on t1.id = t2.id and length(t1.test_data) = t2.len
Demo: http://www.sqlfiddle.com/#!4/66d4c/6
I think the analytic (window) function RANK() is the best way to accomplish this.
SELECT id, test_data FROM (
SELECT id, test_data
, RANK() OVER ( PARTITION BY id ORDER BY LENGTH(test_data) DESC ) AS the_rank
FROM test
) WHERE the_rank = 1
If you want only one record, then you can do the following:
SELECT id, test_data FROM (
SELECT id, test_data
, RANK() OVER ( PARTITION BY id ORDER BY LENGTH(test_data) DESC ) AS the_rank
FROM test
ORDER BY the_rank
) WHERE rownum = 1