I am having this problem... I have following parameters set for my subqueries:
with
params as (select '2018-06-01'::timestamp p_datum_vlozitve_from, '2019-01-01'::timestamp p_datum_vlozitve_to, 0:: double precision glavnica_od, 141::double precision glavnica_do, 141::double precision upnikid)
Select --- MAIN QUERY - BELLOW SUBQUERY
left join (select paketi.id_upnik, sum(specifikacije_postavke.placilo) as pokpravdnistroski
from specifikacije_postavke, specifikacije1, dolzniki_terjatve, paketi, params
where specifikacije1.idizracun=specifikacije_postavke.idizracun and dolzniki_terjatve.referenca=specifikacije1.referenca and paketi.id_paket=dolzniki_terjatve.id_paket
and postavkastroski='4' and obresti=false
and dolzniki_terjatve.glavnica > glavnica_od and dolzniki_terjatve.glavnica < glavnica_do
and dolzniki_terjatve.datum_vlozitve >= p_datum_vlozitve_from and dolzniki_terjatve.datum_vlozitve < p_datum_vlozitve_to
and paketi.id_upnik in(upnikid)
and datumplacila <= date(dolzniki_terjatve.datum_vlozitve) + interval '1 month'
group by paketi.id_upnik)
as tabelapravdnistroski on paketi.id_upnik=tabelapravdnistroski.id_upnik
The last one 141::double precision upnikid goes into part of subquery where the value could be one or more or I have to take all values.
where upniki.upnik_id in (upnikid)
So, if I put i param 141::double precision upnikid, the query is working. If I try to put 141,1000::double precision upnikid, it doesn't work any more. How to put more than one value in this param or maybe all values of upniki.id_upnik or none?
Anyone knows the solution?
If param values for conditions in where are delivered in WITH statement, then list of values can be delivered as array.
Assuming out table is named table1
with
params as (select array[1,2,3] as list)
Select table1.* from table1, params
where table1.position = any (list)
One query example, to play with:
with
params as (select array[1,2,3] as list)
Select table1.* from (
values(1),(2),(3),(4),(5)) as table1(position), params
where table1.position = any (params.list)
Related
I am trying to get the max date by account from 3 different tables and view those dates side by side. I created a separate query for each table, merged the results with UNION ALL, and then wrapped all that in a PIVOT.
The first 2 sections in the link/pic below show what I have been able to accomplish and the 3rd section is what I would like to do.
Query results by step
How can I get the results from 2 of the tables to repeat? Is that possible?
--define var_ent_type = 'ACOM'
--define var_ent_id = '52766'
--define var_dict_id = 113
SELECT
*
FROM
(
SELECT
E.ENTITY_TYPE,
E.ENTITY_ID,
'PERF_SUMMARY' as "TableName",
PS.DICTIONARY_ID,
to_char(MAX(PS.END_EFFECTIVE_DATE), 'YYYY-MM-DD') as "MaxDate"
FROM
RULESDBO.ENTITY E
INNER JOIN PERFORMDBO.PERF_SUMMARY PS ON (PS.ENTITY_ID = E.ENTITY_ID)
WHERE
1=1
-- AND E.ENTITY_TYPE = '&var_ent_type'
-- AND E.ENTITY_ID = '&var_ent_id'
AND PS.DICTIONARY_ID >= 100
AND (E.ACTIVE_STATUS <> 'N' )--and E.TERMINATION_DATE is null )
GROUP BY
E.ENTITY_TYPE,
E.ENTITY_ID,
'PERF_SUMMARY',
PS.DICTIONARY_ID
union all
SELECT
E.ENTITY_TYPE,
E.ENTITY_ID,
'POSITION' as "TableName",
0 as DICTIONARY_ID,
to_char(MAX(H.EFFECTIVE_DATE), 'YYYY-MM-DD') as "MaxDate"
FROM
RULESDBO.ENTITY E
INNER JOIN HOLDINGDBO.POSITION H ON (H.ENTITY_ID = E.ENTITY_ID)
WHERE
1=1
-- AND E.ENTITY_TYPE = '&var_ent_type'
-- AND E.ENTITY_ID = '&var_ent_id'
AND (E.ACTIVE_STATUS <> 'N' )--and E.TERMINATION_DATE is null )
GROUP BY
E.ENTITY_TYPE,
E.ENTITY_ID,
'POSITION',
1
union all
SELECT
E.ENTITY_TYPE,
E.ENTITY_ID,
'CASH_ACTIVITY' as "TableName",
0 as DICTIONARY_ID,
to_char(MAX(C.EFFECTIVE_DATE), 'YYYY-MM-DD') as "MaxDate"
FROM
RULESDBO.ENTITY E
INNER JOIN CASHDBO.CASH_ACTIVITY C ON (C.ENTITY_ID = E.ENTITY_ID)
WHERE
1=1
-- AND E.ENTITY_TYPE = '&var_ent_type'
-- AND E.ENTITY_ID = '&var_ent_id'
AND (E.ACTIVE_STATUS <> 'N' )--and E.TERMINATION_DATE is null )
GROUP BY
E.ENTITY_TYPE,
E.ENTITY_ID,
'CASH_ACTIVITY',
1
--ORDER BY
-- 2,3, 4
)
PIVOT
(
MAX("MaxDate")
FOR "TableName"
IN ('CASH_ACTIVITY', 'PERF_SUMMARY','POSITION')
)
Everything is possible. You only need a window function to make the value repeat across rows w/o data.
--Assuming current query is QC
With QC as (
...
)
select code, account, grouping,
--cash,
first_value(cash) over (partition by code, account order by grouping asc rows unbounded preceding) as cash_repeat,
perf,
--pos,
first_value(pos) over (partition by code, account order by grouping asc rows unbounded preceding) as pos_repeat
from QC
;
See first_value() help here: https://docs.oracle.com/en/database/oracle/oracle-database/19/sqlrf/FIRST_VALUE.html#GUID-D454EC3F-370C-4C64-9B11-33FCB10D95EC
I am trying to create a query where the first column shows the list of the companies and the other 3 columns their revenues per month. This is what I do:
WITH time_frame AS
(SELECT date_trunc('month',NOW())-interval '0 week'),
time_frame1 AS
(SELECT date_trunc('month',NOW())-interval '1 month'),
time_frame2 AS
(SELECT date_trunc('month',NOW())-interval '2 month')
select table1.company_name,
(CASE
WHEN table2.date_of_transaction = (SELECT * FROM time_frame2) THEN sum(table2.amount)
ELSE NULL
END) AS "current week - 2",
(CASE
WHEN table2.date_of_transaction = (SELECT * FROM time_frame1) THEN sum(table2.amount)
ELSE NULL
END) AS "current week - 1",
(CASE
WHEN table2.date_of_transaction = (SELECT * FROM time_frame2) THEN
sum(table2.amount)
ELSE NULL
END) AS "current week - 2"
from table1
join table2 on table2.table1_id = table.id
where table1.company_joined >= '04-20-2019'
group by 1
When I execute the table this comes out: Error running query: column "table2.date_of_transaction" must appear in the GROUP BY clause or be used in an aggregate function LINE 15: WHEN table2.date_of_transaction = (SELECT * FROM time_frame) TH... ^
Do you have any ideas on how to solve it? Thank you.
company name
month1
month2
name 1
£233
£343
name 2
£243
£34
name 3
£133
£43
you can simplify the statement by using the filter() operator
select t1.company_name,
sum(t2.amount) filter (where t2.date_of_transaction = date_trunc('month',NOW())-interval '2 month'),
sum(t2.amount) filter (where t2.date_of_transaction = date_trunc('month',NOW())-interval '1 month'),
sum(t2.amount) filter (where t2.date_of_transaction = date_trunc('month',NOW()))
from table1 t1
join table2 t2 on t2.table1_id = t1.id
where t1.company_joined >= date '2019-04-20'
group by t1.company_name;
If you really want to put the date ranges into a CTE, you only need one:
with dates (r1, r2, r3) as (
values
(date_trunc('month',NOW())-interval '2 month',
date_trunc('month',NOW())-interval '1 month',
date_trunc('month',NOW()))
)
select t1.company_name,
sum(t2.amount) filter (where t2.date_of_transaction = d.r1),
sum(t2.amount) filter (where t2.date_of_transaction = d.r2),
sum(t2.amount) filter (where t2.date_of_transaction = d.r3)
from table1 t1
cross join dates d
join table2 t2 on t2.table1_id = t1.id
where t1.company_joined >= date '2019-04-20'
group by t1.company_name
;
The CTE dates returns a single row with three columns and thus the cross join doesn't change the resulting number of rows.
I have 3 tables:
with current_exclusive as(
select id_station, area_type,
count(*) as total_entries
from c1169.data_cashier
where id_station IN(2439,2441,2443,2445,2447,2449) and date >= '2017-10-30' and date <= '2017-12-30'
group by id_station, area_type
), current_table as(
select id_station, area_type,
sum(total_time) filter (where previous_status = 1) as total_time
from c1169.data_table
where id_station IN(2439,2441,2443,2445,2447,2449) and date >= '2017-10-30' and date < '2017-12-30'
group by id_station, area_type
), current_cashier as(
select id_station, area_type,
sum(1) as total_transactions
from c1169.data_cashier
where id_station IN(2439,2441,2443,2445,2447,2449) and date >= '2017-10-30' and date < '2017-12-30'
group by id_station, area_type
)
select *
from current_exclusive
full join current_table on current_exclusive.id_station = current_table.id_station and current_exclusive.area_type = current_table.area_type
full join current_cashier on current_exclusive.id_station = current_cashier.id_station and current_exclusive.area_type = current_cashier.area_type
and the result is:
but my expected result is:
Are there any way to select * and show the expected result? Because when I do full join then id_station and area_type can be null in some tables, so it very hard to choose which column is not null.
Like: select case id_station is not null then id_station else id_station1 end, but I have up to 10 tables so can not do in select case
Use USING, per the documentation:
USING ( join_column [, ...] )
A clause of the form USING ( a, b, ... ) is shorthand for ON left_table.a = right_table.a AND left_table.b = right_table.b .... Also, USING implies that only one of each pair of equivalent columns will be included in the join output, not both.
select *
from current_exclusive
full join current_table using (id_station, area_type)
full join current_cashier using (id_station, area_type)
You cannot accomplish anything if you insist on using select *, since you are getting the values from different tables.
The option you have is to include a COALESCE block which gives you the first non-null value from the list of columns.
So, you could use.
select COALESCE( current_exclusive.id_station, current_table.id_station, current_cashier.id_station ) as id_station ,
COALESCE( current_exclusive.area_type , current_table.area_type, current_cashier.area_type ) as area_type ,.....
...
from current_exclusive
full join current_table..
...
I'm having an issue using a column alias for a join in a cte. Invalid column name on the line with RowNumber2 >= (t1.RowNumber - 20) Anyone have a suggestion? Thanks..
DECLARE #latestDate Date = dbo.LatestDateWithPricingVolCountOver4k()
;WITH AllSymbsAndDates AS
(
SELECT
ROW_NUMBER() OVER (PARTITION BY Symbol ORDER BY TradingDate) AS RowNumber,
Symbol, TradingDate
FROM tblSymbolsMain
CROSS JOIN tblTradingDays
WHERE TradingDate <= #latestDate
),
SymbsDatesGrouped AS
(
SELECT * FROM
(
SELECT
t1.Symbol, t1.TradingDate, t2.TradingDate AS TradingDate2, t1.RowNumber,
t2.RowNumber AS RowNumber2
FROM AllSymbsAndDates t1
JOIN AllSymbsAndDates t2 ON t1.Symbol = t2.Symbol
AND RowNumber2 >= (t1.RowNumber - 20)
) t
)
SELECT
Symbol, TradingDate, TradingDate2, RowNumber, RowNumber2
FROM
SymbsDatesGrouped
ORDER BY
Symbol, TradingDate, TradingDate2
You can't reference a column alias in the WHERE or JOIN clauses - actually the only clause where you can reference an alias from the SELECT list is either in the ORDER BY (or in an outer scope, e.g. selecting from a subquery or CTE).
In this case, the solution is pretty trivial. Why not just say:
AND t2.RowNumber >= (t1.RowNumber - 20)
?
I have written sql statement :
select * from (
select count(*) as NumberofSignals,signals.transmitter_account,signals.class,signals.type,signals.signal_mode,
signals.area_id,signals.sector_id,signals.region_info_id,signals.zone_info_id,signals.user_id,signals.device_id,
signals.panel_name,signals.panel_id,signals.sector_name,signals.region_code,signals.area_name,signals.zone_code,
signals.description,signals.transmitter_name,signals.transmitter_id,signals.color,'event' as Event,get_name(signals.id,'event') as event_value,
'packetnumber' as packetnumber,get_name(signals.id,'packetnumber') as packetnumber_value,wm_concat(distinct get_name(signals.id,'repeater')) as repeater,
round(avg(get_name(signals.id,'signallevel'))) as avg_signallevel,min(to_char(signals.signal_forming_time, 'yyyy/mm/dd hh24:mi:ss')) as formingtime,
get_name(signals.id,'address') as address,get_name(signals.id,'username') as username,get_name(signals.id,'chaneltype') as channeltype,
get_name(signals.id,'code') as code,get_name(signals.id,'account') as account
from signals,signal_custom_fields where signals.id = signal_custom_fields.signal_id and
signals.id in (select id from (select id,rownum num from((select signals.id
from signals,signal_custom_fields where signal_custom_fields.field_name = 'event'
and signal_custom_fields.field_value is not null and signals.id = signal_custom_fields.signal_id
and signals.signal_forming_time >= to_date('2011/5/10 14:34:44', 'yyyy/mm/dd hh24:mi:ss')
AND signals.signal_forming_time <= to_date('2011/5/10 15:34:44', 'yyyy/mm/dd hh24:mi:ss'))
intersect (select distinct signals.id from signals,signal_custom_fields
where signal_custom_fields.field_name = 'packetnumber' and signal_custom_fields.field_value is not null
and signals.id = signal_custom_fields.signal_id
and signals.signal_forming_time >= to_date('2011/5/10 14:34:44', 'yyyy/mm/dd hh24:mi:ss')
AND signals.signal_forming_time <= to_date('2011/5/10 15:34:44', 'yyyy/mm/dd hh24:mi:ss')))
order by id desc)) group by 'event',signals.transmitter_account,signals.class,
signals.type,signals.signal_mode,signals.area_id,signals.sector_id,signals.region_info_id,signals.zone_info_id,
signals.user_id,signals.device_id,signals.panel_name,signals.panel_id,signals.sector_name,signals.region_code,
signals.area_name,signals.zone_code,signals.description,signals.transmitter_name,signals.transmitter_id,
signals.color, get_name(signals.id,'event'), 'packetnumber',get_name(signals.id,'username'),
get_name(signals.id,'chaneltype'),
get_name(signals.id,'code'),
get_name(signals.id,'account'), get_name(signals.id,'packetnumber'),get_name(signals.id,'address'),
TO_CHAR(signals.signal_forming_time ,'dd/mm/yyyy hh24'),
TRUNC(to_number(to_char(signals.signal_forming_time ,'mi'))/(30))
order by event)where rownum < 300
and here i get the first 300 rows, but how i need to rewright this statment to retrieve second 300 rows ???
Your query doesn't have the rownum listed in the first nested table. Add a rownum column in the first nested table then you can do a between function in the where clause at the top level:
--create a demo table
DROP TABLE paging_test;
CREATE TABLE paging_test AS
(SELECT rownum x FROM user_tables
);
--count how many records exist (in my case there is 821)
SELECT COUNT(*)
FROM paging_test;
--get the first 300 rows
SELECT *
FROM
(SELECT rownum rn, x FROM paging_test ORDER BY x
) pt
WHERE pt.rn BETWEEN 1 AND 300 ;
--get the next 300 rows
SELECT *
FROM
(SELECT rownum rn, x FROM paging_test ORDER BY x
) pt
WHERE pt.rn BETWEEN 300 AND 600 ;
You might also be interested in my reference:
References:
http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:948366252775