Group function in where IN clause - sql

I have two tables having seq_no column:
select max(SEQ_NO) from final_prices;
select max(SEQ_NO) from price_loads;
I want to insert into a third table: archive_load from final_prices table on the condition that if the MAX(SEQ_NO) in final_prices exists in price_loads table
I am writing this query:
insert
into xx_label_prices_arc_temp
(select * from xx_label_final_prices where max (seq_no) in (select max(seq_no) from xx_label_price_loads));
It gives me the error:
group function is not allowed here
How can I insert based on this logic?

You can do:
insert into xx_label_prices_arc_temp
select *
from final_prices
where exists (
select 1 from price_loads where seq_no = (select max(seq_no) from final_prices)
)

Related

Insert/join table on multiple conditions

I’ve a table that looks like this:
Table A
Version,id
5060586,22285
5074515,22701
5074515,22285
7242751,22701
7242751,22285
I want to generate a new key called groupId that is inserted as my example below:
Table A
Version,id,groupId
5060586,22285,1
5074515,22701,2
5074515,22285,2
7242751,22701,2
7242751,22285,2
I want the groupId to be the same as long as the id's are the same in the different versions. So for example version 5074515 and 7242751 has the same id's so therefor the groupId will be the same. If all the id's aren't the same a new groupId should be added as it has in version 5060586.
How can i solve this specific problem in SQL oracle?
One approach is to create a unique value representing the set of ids in each version, then assign a groupid to the unique values of that, then join back to the original data.
INSERT ALL
INTO t (version,id) VALUES (5060586,22285)
INTO t (version,id) VALUES (5074515,22701)
INTO t (version,id) VALUES (5074515,22285)
INTO t (version,id) VALUES (7242751,22701)
INTO t (version,id) VALUES (7242751,22285)
SELECT 1 FROM dual;
WITH groups
AS
(
SELECT version
, LISTAGG(id,',') WITHIN GROUP (ORDER BY id) AS group_text
FROM t
GROUP BY version
),
groupids
AS
(
SELECT group_text, ROW_NUMBER() OVER (ORDER BY group_text) AS groupid
FROM groups
GROUP BY group_text
)
SELECT t.*, groupids.groupid
FROM t
INNER JOIN groups ON t.version = groups.version
INNER JOIN groupids ON groups.group_text = groupids.group_text;
dbfiddle.uk
You can use:
UPDATE tableA t
SET group_id = ( SELECT COUNT(DISTINCT id)
FROM TableA x
WHERE x.Version <= t.version );
Which, for the sample data:
CREATE TABLE TableA (
Version NUMBER,
id NUMBER,
group_id NUMBER
);
INSERT INTO TableA (Version, id)
SELECT 5060586,22285 FROM DUAL UNION ALL
SELECT 5074515,22701 FROM DUAL UNION ALL
SELECT 5074515,22285 FROM DUAL UNION ALL
SELECT 7242751,22701 FROM DUAL UNION ALL
SELECT 7242751,22285 FROM DUAL;
Then, after the update:
SELECT * FROM tablea;
Outputs:
VERSION
ID
GROUP_ID
5060586
22285
1
5074515
22701
2
5074515
22285
2
7242751
22701
2
7242751
22285
2
db<>fiddle here

Copy A table to another Table in PostgreSQL

I have two Table
one is student_record_temp
id
name
roll
1
Shadman
2
2
Adnan
3
Now I want to copy the row in student_record where the name is shadman and it returns both student_record_temp and student_record id
I am trying to solve this in
INSERT INTO student_record (name,rool) select name,roll from student_record_temp
FROM student_record_temp WHERE name='shadman' RETURNING student_record.id,student_record_temp.id
ERROR: missing FROM-clause entry for table "student_record_temp"
LINE 8: student_record.id,student_record_temp.id
but I got an error and how I can solve this.
To copy a table with partial data from an existing table
CREATE TABLE new_table AS
SELECT
*
FROM
existing_table
WHERE
condition;
The condition in the WHERE clause of the query defines which rows of the existing table will be copied to the new table
or you can use this:
INSERT INTO TABLE1 (id, col_1, col_2, col_3)
SELECT id, 'data1', 'data2', 'data3'
FROM TABLE2
WHERE col_a = 'something';
You can't be returning data from select in the insert query. You can use two scenarios:
second scenario
If name column data from student_record_temp table is unique. you can use join in returning query:
insert into student_record as sr (name, roll)
select srt.name, srt.roll
from student_record_temp srt
where name = 'shadman'
returning sr.id, (select id from student_record_temp r_srt where r_srt.name = sr.name);
first scenario
If name column data from student_record_temp table is not unique. you have to create temp unique field and use from that
with select_data as (
select srt.id, srt.name, srt.roll, row_number() OVER (ORDER BY id) AS rn
from student_record_temp srt
where name = 'shadman'),
add_data as (
insert into student_record as sr (name, roll)
select sd.name, sd.roll
from select_data sd
order by sd.id
returning sr.id)
select ad.id as insert_id,
sd.id as select_id
from (select id, row_number() over (order by id) as rn from add_data) ad
inner join select_data sd on ad.rn = sd.rn;

Perform a function after union of two tables

I have two tables that I want to union together then perform some math functions on the combined table.
I know how to do the math for each separate table, but throwing in a union table to go off of is out of my league.
Here's the math for one table using column header "UnitsReceived" and "AsnPsUnits"
The other table would have headers: "cUnitsReceived" and "cAsnPsUnits"
select VendName,
1-abs(((cast(sum(UnitsReceived) as decimal(5,0))) - (cast(sum(AsnPsUnits) as decimal(5,0)))) /(cast(sum(AsnPsUnits) as decimal(5,0)))) as ASNpsAcc
from VenTest2
where ID<20
group by VendName
How would I perform this function after the union of two tables?
You'll need to get the unioned tables into some table object before performing your function. This could be done using:
A Common Table Expression
with cte as (
select ID, VALUE from A
union all
select ID, VALUE from B
)
select
*
,myfunction(VALUE) as MyFunctionResult
from
cte
A temp table
select ID, VALUE into #myTempTable from A
insert into #myTempTable select ID, VALUE from B
select
*
,myfunction(VALUE) as MyFunctionResult
from
#myTempTable
A table variable
declare #myTableVariable table (ID int, VALUE decimal)
insert into #myTableVariable
select ID, VALUE from A
union all
select ID, VALUE from B
select
*
,myfunction(VALUE) as MyFunctionResult
from
#myTableVariable
A sub query
select
*
,myfunction(VALUE) as MyFunctionResult
from
(
select ID, VALUE from A
union all
select ID, VALUE from B
) mySubQuery
This will help with the subq being the union
select VendName,
1-abs(((cast(sum(UnitsReceived) as decimal(5,0))) - (cast(sum(AsnPsUnits) as decimal(5,0)))) /(cast(sum(AsnPsUnits) as decimal(5,0)))) as ASNpsAcc
from
(
select ID, UnitsReceived, AsnPsUnits from VenTest2 where ID<20
union
select ID1, UnitsReceived1, AsnPsUnits1 from VenTest1
)a
group by VendName
This is not the way, brothers:
select VendName,
1-abs(((cast(sum(UnitsReceived) as decimal(10,2))) - (cast(sum(AsnPsUnits) as decimal(10,2)))) /(cast(sum(AsnPsUnits) as decimal(10,2)))) as ASNpsAcc
from VenTest2
where ID<10
group by VendName
union
select cVendName,
1-abs(((cast(sum(cUnitsReceived) as decimal(10,2))) - (cast(sum(casnpsunits) as decimal(10,2)))) /(cast(sum(cAsnPsUnits) as decimal(10,2)))) as ASNpsAcc
from CTest
where id <10
group by cvendname

How to exclude rows in sql server insert statement?

I have a statement like this
insert into A (id, nid)
(
select id, 100 as nid
from B
group by id
)
this works, but the problem is table A, has a primary key constraint on (id, nid), and some of the rows in the computed nested query, already exist in table A. How can I exclude them from being included in the nested query?
Thanks
You could use EXCEPT:
insert into A (id, nid)
select id, 100 as nid
from B
group by id
EXCEPT
SELECT id, nid
FROM A;
Just check if the rows exist...
insert into A (id, nid)
select id, 100 as nid
from B
WHERE NOT EXISTS (SELECT * FROM A WHERE A.id = B.id AND A.nid = 100)
group by id
PS: the parenthesis around your select are unnecessary
Add Where clause:
insert A (id, nid)
select id, 100 as nid
from B
Where Not exists (Select * from A
Where id = B.Id
and nid = 100)
group by id

Counting repeated data

I'm trying to get maximum repeat of integer in table I tried many ways but could not make it work. The result I'm looking for is as:
"james";"108"
As this 108 when I concat of two fields loca+locb repeated two times but others did not I try below sqlfiddle link with sample table structure and the query I tried... sqlfiddle link
Query I tried is :
select * from (
select name,CONCAT(loca,locb),loca,locb
, row_number() over (partition by CONCAT(loca,locb) order by CONCAT(loca,locb) ) as att
from Table1
) tt
where att=1
please click here so you can see complete sample table and query I tried.
Edite: adding complete table structure and data:
CREATE TABLE Table1
(name varchar(50),loca int,locb int)
;
insert into Table1 values ('james',100,2);
insert into Table1 values ('james',100,3);
insert into Table1 values ('james',10,8);
insert into Table1 values ('james',10,8);
insert into Table1 values ('james',10,7);
insert into Table1 values ('james',10,6);
insert into Table1 values ('james',0,7);
insert into Table1 values ('james',10,0);
insert into Table1 values ('james',10);
insert into Table1 values ('james',10);
and what I'm looking for is to get (james,108) as that value is repeated two time in entire data, there is repetion of (james,10) but that have null value of loca so Zero value and Null value is to be ignored only those to be considered that have value in both(loca,locb).
SQL Fiddle
select distinct on (name) *
from (
select name, loca, locb, count(*) as total
from Table1
where loca is not null and locb is not null
group by 1,2,3
) s
order by name, total desc
WITH concat AS (
-- get concat values
SELECT name,concat(loca,locb) as merged
FROM table1 t1
WHERE t1.locb NOTNULL
AND t1.loca NOTNULL
), concat_count AS (
-- calculate count for concat values
SELECT name,merged,count(*) OVER (PARTITION BY name,merged) as merged_count
FROM concat
)
SELECT cc.name,cc.merged
FROM concat_count cc
WHERE cc.merged_count = (SELECT max(merged_count) FROM concat_count)
GROUP BY cc.name,cc.merged;
SqlFiddleDemo
select name,
newvalue
from (
select name,
CONCAT(loca,locb) newvalue,
COUNT(CONCAT(loca,locb)) as total,
row_number() over (order by COUNT(CONCAT(loca,locb)) desc) as att
from Table1
where loca is not null
and locb is not null
GROUP BY name, CONCAT(loca,locb)
) tt
where att=1