I am using oracle sql developer and have a query whereby I want to apply the same query on different columns, then stack the resulting output into a single data table.
For example, the query looks like the following:
select BG_TURNOVER, MARKET, count(*)
FROM( SELECT (CASE
WHEN sports_returns_l90d = 0
THEN 'sports_returns_l90d_0'
WHEN sports_returns_l90d > 0 AND sports_returns_l90d <= 500
THEN 'sports_returns_l90d_0_500'
WHEN sports_returns_l90d > 500 AND sports_returns_l90d <= 1000
THEN 'sports_returns_l90d_500_1000'
WHEN sports_returns_l90d > 1000 AND sports_returns_l90d <= 2500
THEN 'sports_returns_l90d_1000_2500'
WHEN sports_returns_l90d > 2500 AND sports_returns_l90d <= 5000
THEN 'sports_returns_l90d_2500_5000'
ELSE 'sports_returns_l90d_5000+'
END) AS BG_TURNOVER, MARKET
FROM PRODUCT_TABLE ) group by BG_TURNOVER, MARKET;
Which looks like:
BG_TURNOVER MARKET count
sports_returns_l90d_5000+ Romania 497864
sports_returns_l90d_1000_2500 Hungary 2986
sports_returns_l90d_0 Belgium Dutch 14103
sports_returns_l90d_5000+ Intl French 6745
...
However, I wanted to apply multiple columns in place of sports_returns_l90d. Then have the string match that column name.
For example:
select BG_TURNOVER, MARKET, count(*)
FROM( SELECT (CASE
WHEN X = 0
THEN 'X_0'
WHEN X > 0 AND X <= 500
THEN 'X_0_500'
WHEN X > 500 AND X <= 1000
THEN 'X_500_1000'
WHEN X > 1000 AND X <= 2500
THEN 'X_1000_2500'
WHEN X > 2500 AND X <= 5000
THEN 'X_2500_5000'
ELSE 'X_5000+'
END) AS BG_TURNOVER, MARKET
FROM PRODUCT_TABLE ) group by BG_TURNOVER, MARKET;
Whereby X takes the column names: sports_return_l90d, sports_returns, bingo_returns, is there a way to iterate over all of these?
If you have the sports_return_l90d, sports_returns, bingo_returns values in different columns such as:
CREATE TABLE product_table ( sports_return_l90d, sports_returns, bingo_returns, market ) AS
SELECT 1000, 5500, 1, 'AAA' FROM DUAL CONNECT BY LEVEL <= 10;
Then you can use:
SELECT type ||
CASE
WHEN bg_turnover = 0
THEN '_0'
WHEN bg_turnover > 0 AND bg_turnover <= 500
THEN '_0_500'
WHEN bg_turnover > 500 AND bg_turnover <= 1000
THEN '_500_1000'
WHEN bg_turnover > 1000 AND bg_turnover <= 2500
THEN '_1000_2500'
WHEN bg_turnover > 2500 AND bg_turnover <= 5000
THEN '_2500_5000'
ELSE '_5000+'
END AS BG_TURNOVER,
MARKET,
count(*)
FROM PRODUCT_TABLE
UNPIVOT (
bg_turnover FOR type IN (
sports_return_l90d AS 'sports_return_l90d',
sports_returns AS 'sports_returns',
bingo_returns AS 'bingo_returns'
)
)
GROUP BY
type,
CASE
WHEN bg_turnover = 0
THEN '_0'
WHEN bg_turnover > 0 AND bg_turnover <= 500
THEN '_0_500'
WHEN bg_turnover > 500 AND bg_turnover <= 1000
THEN '_500_1000'
WHEN bg_turnover > 1000 AND bg_turnover <= 2500
THEN '_1000_2500'
WHEN bg_turnover > 2500 AND bg_turnover <= 5000
THEN '_2500_5000'
ELSE '_5000+'
END,
MARKET;
Which outputs:
BG_TURNOVER
MARKET
COUNT(*)
sports_return_l90d_500_1000
AAA
10
sports_returns_5000+
AAA
10
bingo_returns_0_500
AAA
10
fiddle
Related
I have columns like below
Annot Patient
X 100
X 100
N 100
N 100
S 100
S 100
V 100
N 100
N 100
S 100
I'm expecting output like below
I need the "X" value to be "0" always and all other variable groups should increment from 1,2,3,...
Annot Patient segment
N 100 1
N 100 1
X 100 0
X 100 0
S 100 2
S 100 2
V 100 3
N 100 4
N 100 4
S 100 5
You can use dense_rank() and case logic:
select t.*,
(case when annot = 'X' then 0
else dense_rank() over (partition by patient, (case when annot = 'X' then 'X' end) order by annot
end) as segment
from t;
I've this Teradata query:
WITH ID(ROW_NUM) AS
(
SELECT ROW_NUMBER() OVER (ORDER BY PRSN_ID) AS ROW_NUM
FROM MyTable
WHERE ACTIVE_IND = 'Y'
GROUP BY PRSN_ID
)
SELECT ROW_NUM-ROW_NUM MOD 2 AS FirstIndex,
ROW_NUM-(ROW_NUM-1) MOD 2 AS SecondIndex
FROM ID
WHERE ROW_NUM MOD 2=1
This query will generate an ID column, and the result will be something like this:
FirstIndex SecondIndex
0 1
2 3
4 5
. .
. .
etc etc
I would like to change the selection to be a batch through a 1000 records like below:
FirstIndex SecondIndex
0 1000
1001 2000
2001 3000
3001 4000
. .
. .
etc etc
Your help is appreciated.
Your calculation is way to complex:
ROW_NUM-1 AS FirstIndex,
ROW_NUM AS SecondIndex
To get your requested range you simply need to modify the calculation, e.g.
SELECT
CASE WHEN ROW_NUM = 1 THEN 0 ELSE SecondIndex-999 END AS FirstIndex,
(ROW_NUM+2)/2 * 1000 AS SecondIndex
FROM ID
WHERE ROW_NUM MOD 2=1
But what do you want to do with that result, batch what?
Edit:
It's still unclear why you need a 2nd table to calculate the ranges, but this creates ranges starting from 1 for any pagesize of n rows:
WITH ID(ROW_NUM) AS
( -- just to get some rows
SELECT day_of_calendar AS row_num
FROM sys_calendar.CALENDAR
WHERE row_num BETWEEN 1 AND 10
)
SELECT 1000 AS RowsPerPage,
Row_Num AS page_num,
rownum_to - (RowsPerPage-1) AS rownum_from,
page_num * RowsPerPage AS rownum_to
FROM ID
GROUP BY page_num
ORDER BY page_num
RowsPerPage page_num rownum_from rownum_to
1000 1 1 1000
1000 2 1001 2000
1000 3 2001 3000
1000 4 3001 4000
1000 5 4001 5000
1000 6 5001 6000
1000 7 6001 7000
1000 8 7001 8000
1000 9 8001 9000
1000 10 9001 10000
Hi you can try the below query once, this will give you the desired sequence.
select ROW_NUM,FirstIndex, coalesce(case when SecondIndex<1000 then (SecondIndex+2000) else (SecondIndex+1000) end,FirstIndex+1001) as SecondIndex from
(SELECT ROW_NUM,
case when (FirstIndex < 1000) then (FirstIndex+1001) else (FirstIndex+1) end as FirstIndex,
(min(FirstIndex) OVER(ORDER BY FirstIndex ROWS BETWEEN 1 FOLLOWING AND 1 FOLLOWING)) SecondIndex
FROM (Select (ROW_NUMBER() OVER (ORDER BY PRSN_ID)-1) AS ROW_NUM,(ROW_NUMBER() OVER (ORDER BY PRSN_ID)-1) AS FirstIndex from Mytable GROUP BY PRSN_ID) A) B
order by ROW_NUM;
Need your help with a SQL Query and how should I write it?
I have a table with total_value and order_id and would like to find the number of orders whose total value is in the range of 0-50, 51-100, over 100
Thank you !
you want a case statement.
something like:
select count(order_id),
value_range
from
(select order_id,
total_value,
case when total_value between 0 and 50 then '0-50'
when total_value between 51 and 100 then '51-100'
when total_value > 100 then '100'
end as value_range
from table)a
group by value_range
Perhaps this will work for you:
select count(order_id),
valueRange
from
(select order_id,
total_value,
case when total_value between 0 and 50 then '0-50'
when total_value between 51 and 100 then '51-100'
when total_value > 100 then '100'
end as valueRange
from table)a
Group by valueRange
Using Conditional SUM:
SELECT SUM(CASE WHEN Total_Value BETWEEN 0 AND 50 THEN 1 ELSE 0 END) As Range1
, SUM(CASE WHEN Total_Value BETWEEN 51 AND 100 THEN 1 ELSE 0 END) As Range2
, SUM(CASE WHEN Total_Value > 100 THEN 1 ELSE 0 END) As Range3
FROM your_table
I have a table, structure like this:
BID_FK AccountID Amount
1 1-1-1-1-1-1-1 4050
1 1-1-1-1-1-1-1 4050
1 1-1-1-1-1-1-1 4050
1 1-1-1-1-1-1-1 4050
1 1-1-1-1-1-1-2 500
1 1-1-1-1-1-1-2 500
1 1-1-1-1-1-1-2 500
1 1-1-1-1-1-1-2 500
2 1-1-1-1-1-1-1 6580
2 1-1-1-1-1-1-1 6580
2 1-1-1-1-1-1-1 6580
2 1-1-1-1-1-1-1 6580
2 1-1-1-1-2-1-1 1000
2 1-1-1-1-2-1-1 1000
2 1-1-1-1-2-1-1 1000
2 1-1-1-1-2-1-1 1000
I want to query for getting out put like this :
AccountID Amount(BID_FK = 1) Amount (BID_FK = 2)
1-1-1-1-1-1-1 16200 26320
1-1-1-1-1-1-2 2000 0
1-1-1-1-2-1-1 0 4000
With minimum query cost because I have large number of data.
Any help would be highly appreciated!
Maybe something like this could help?
SELECT
AccountID,
SUM(CASE WHEN BID_FK=1 THEN Amount ELSE 0 END) AMOUNT1,
SUM(CASE WHEN BID_FK=2 THEN Amount ELSE 0 END) AMOUNT2
FROM yourtable
GROUP BY AccountId
SELECT AccountID,
SUM( CASE WHEN BID_FK=1 THEN Amount ELSE 0 END) AS `Amount(BID_FK = 1)`
SUM( CASE WHEN BID_FK=2 THEN Amount ELSE 0 END) AS `Amount(BID_FK = 2)`
FROM yourTable
GROUP BY AccountID
I need to write a SQL query which will get me those rows from the table which have the max value of files.
The database table is as follows:
> ID status dept files
>
> > 1 1 23 1256637314
> >
> > 1 1 39 1256642968
> >
> > 2 0 85 1256551419
> >
> > 2 1 90 1256642968
> >
> > 2 1 93 1256810937
> >
> > 3 0 20 1256642968
> >
> > 5 1 342 1256810937
Now from this table i want to get those rows which have the maximum files grouping by ID:
> ID status dept files
>
> 1 1 39 1256642968
>
> 2 1 93 1256810937
>
> 3 0 20 1256642968
>
> 5 1 342 1256810937
Any suggestions??
Thanks.
i tried this but this is not right
Select ID, Status, dept,files
from SLAStat
where files in (Select Max(files) from SLAStat group by ID)
2 1 90 1256642968
1 1 39 1256642968
3 0 20 1256642968
5 1 342 1256810937
2 1 93 1256810937
Replace #t1 by your table:
With idT as (
select ID
from #t1
group by id
)
select applyT.*
from idT p
CROSS APPLY (
select top 1 * from #t1 where ID=p.ID order by files desc
) as applyT
SELECT DISTINCT a.ID, a.Status, a.Dept, a.Files
FROM table a
INNER JOIN (
SELECT ID, MAX(files) AS Files
FROM table
GROUP BY ID) b ON a.ID = b.ID AND a.Files = b.Files
SELECT MAX(files) as max_files, id, status, dept
FROM table
GROUP BY id
I may be over-simplifying the problem, but:
select top 5 * from SLAStat order by files desc;