INSERT new row consolidate similar rows - sql

Here is what I need to accomplish:
INSERT a new row into t_order by combining two or more rows from the same table (t_order) where all values are the same except for order_id (Identity) and order_number
The New Row will represent a consolidated order.
Two orders going to the same address get combined into one
Example Table before Insert
order_id order_number ship_addrs1 ship_to_zip
-------- ------------ ----------- -----------
1 ABC001 111 1st St 11111
2 ABC002 123 Main St 12345 <--- Source Row
3 ABC003 123 Main St 12345 <--- Source Row
4 ABC004 111 2nd St 11111
Result After Insert (Source orders must remain)
order_id order_number ship_addrs1 ship_to_zip
-------- ------------ ----------- -----------
1 ABC001 111 1st St 11111
2 ABC002 123 Main St 12345
3 ABC003 123 Main St 12345
4 ABC004 111 2nd St 11111
5 ABC005 123 Main St 12345 <--- New Row
I have considered using the following code to accomplish this but not sure what I need to do to consolidate the three rows.
SELECT * INTO tmp_order_cosolidation
FROM t_order
WHERE order_id = 1 AND order_number = ABC002
ALTER TABLE tmp_order_cosolidation
DROP COLUMN order_id, ordern_number
INSERT INTO t_order
SELECT *
FROM tmp_order_cosolidation;
DROP TABLE tmp_order_cosolidation ;
Thank you in advance for your answers

Your order table should have a few more columns to show whether the order is a consolidation, eligible for consolidation, or has already been consolidated. Here is my proposed solution, which has added columns. All inferred columns are in CAPS.
--VIEW ROWS TO INSERT
select count(order_id),ship_addrs1,ship_to_zip2
from t_order
where CONSOL_ELIGIBLE = 'Y' and CONSOL_COMPLETED = 'N'
group by ship_addrs1,ship_to_zip2
having count(order_id) > 1
--TEMP TABLE FOR INSERT
declare #tmptable TABLE (total_orders int,ship_addrs1 nvarchar(50),ship_to_zip2 nvarchar(50),CONSOL_ELIGIBLE nvarchar(1))
insert into #tmptable (total_orders, ship_addrs1,ship_to_zip2,CONSOL_ELIGIBLE)
(select count(order_id),ship_addrs1,ship_to_zip2,'N'
from t_order
where CONSOL_ELIGIBLE = 'Y' and CONSOL_COMPLETED = 'N'
group by ship_addrs1,ship_to_zip2
having count(order_id) > 1)
--INSERT FROM TEMP TABLE
insert into ORDER_TABLE (total_orders, ship_addrs1,ship_to_zip2,CONSOL_ELIGIBLE)
(select total_orders, ship_addrs1,ship_to_zip2,CONSOL_ELIGIBLE
from #tmptable)

Related

More than one occurrence from table

create table customer (cif number, name varchar(20),mobile number);
insert into table customer values(121,'ANT',789);
insert into table customer values(122,'ANT',789);
insert into table customer values(123,'ENT',789);
insert into customer values(124,'ENT',789);
insert into customer values(125,'BEE',123);
insert into customer values(126,'BEE',123);
insert into customer values(127,'BRO',789);
insert into customer values(128,'FIO',789);
commit;
I want retrieve data from customer table based on name and mobile more than one occurrences.
Can anyone help me out
Result like
You can use COUNT() aggregation as Analytic function along with grouping by those columns through use of PARTITION BY clause as
SELECT cif, name, mobile
FROM (SELECT c.*,
COUNT(*) OVER (PARTITION BY name, mobile) AS cnt
FROM customer c )
WHERE cnt > 1
Demo
Source:
SQL> select * From customer;
CIF NAME MOBILE
---------- -------------------- ----------
121 ANT 789
122 ANT 789
123 ENT 789
124 ENT 789
125 BEE 123
126 BEE 123
127 BRO 789
128 FIO 789
8 rows selected.
Based on result you posted, you're looking for rows that aren't unique per name and mobile. If that's so, here's another option:
SQL> select *
2 from customer a
3 where exists (select null
4 from customer b
5 where b.name = a.name
6 and b.mobile = a.mobile
7 group by b.name, b.mobile
8 having count(*) > 1
9 );
CIF NAME MOBILE
---------- -------------------- ----------
121 ANT 789
122 ANT 789
123 ENT 789
124 ENT 789
125 BEE 123
126 BEE 123
6 rows selected.
SQL>

Count values separately until certain amount of duplicates SQL

I need a Statement that selects all patients and the amount of their appointments and when there are 3 or more appointments that are taking place on the same date they should be counted as one appointment
That is what my Statement looks so far
SELECT PATSuchname, Count(DISTINCT AKTDATUM) AS AKTAnz
FROM tblAktivitaeten
LEFT OUTER JOIN tblPatienten ON (tblPatienten.PATID=tblAktivitaeten.PATID)
WHERE (AKTDeleted<>'J' OR AKTDeleted IS Null)
GROUP BY PATSuchname
ORDER BY AKTAnz DESC
The result should look like this
PATSuchname Appointments
----------------------------------------
Joey Patner 13
Billy Jean 15
Example Name 13
As you can see Joey Patner has 13 Appointments, in the real table though he has 15 appointments but three of them have the same Date and because of that they are only counted as 1
So how can i write a Statement that does exactly that?
(I am new to Stack Overflow, sorry if the format I use is wrong and tell me if it is.
In the table it looks like this.
tblPatienten
----------
PATSuchname PATID
------------------------
Joey Patner 1
Billy Jean 2
Example Name 3
tblAktivitaeten
----------
AKTDatum PATID AKTID
-----------------------------------------
08.02.2021 1 1000 ----
08.02.2021 1 1001 ---- So these 3 should counted as 1
08.02.2021 1 1002 ----
09.05.2021 1 1003
09.07.2021 2 1004 -- these 2 shouldn't be counted as 1
09.07.2021 2 1005 --
Two GROUP BY should do it:
SELECT
x.PATID, PATSuchname, SUM(ApptCount)
FROM (
SELECT
PATID, AKTDatum, CASE WHEN COUNT(*) < 3 THEN COUNT(*) ELSE 1 END AS ApptCount
FROM tblAktivitaeten
GROUP BY
PATID, AKTDatum
) AS x
LEFT JOIN tblPatienten ON tblPatienten.PATID = x.PATID
GROUP BY
x.PATID, PATSuchname

How to merge and display columns of 2 tables?

hope someone can help!
I have 2 tables:
**Table A**
Ref_No 1234
Shipment Loc MNL
Shipment date 05/03
Shipment Qty 100
**Table B**
Ref_No 1234
Received Loc MNL
Received date 06/03
Received Qty 90
How do I query and display all these columns in my table? The other 10 quantities is not showing up in Table B.
Rec Loc MNL
Ship Date 05/03
Rec Date 06/03
Ship Qty 100
Rec Qty 90
If I understood you correctly, that would be (outer?) join of these two tables:
SQL> alter session set nls_date_format ='dd.mm.yyyy';
Session altered.
SQL> with
2 a (ref_no, shipment_loc, shipment_date, shipment_qty) as
3 (select 1234, 'MNL', date '2020-03-05', 100 from dual),
4 b (ref_no, received_loc, received_date, received_qty) as
5 (Select 1234, 'MNL', date '2020-03-06', 90 from dual)
6 select b.received_loc,
7 a.shipment_date,
8 b.received_date,
9 a.shipment_qty,
10 b.received_qty
11 from a left join b on a.ref_no = b.ref_no;
REC SHIPMENT_D RECEIVED_D SHIPMENT_QTY RECEIVED_QTY
--- ---------- ---------- ------------ ------------
MNL 05.03.2020 06.03.2020 100 90
SQL>

Is there any way to make FULL OUTER JOIN table match with the correct record?

I'm trying to join two table using FULL OUTER JOIN that two table have different row of data and the column between this two table are same.
Table 2 FULL OUTER JOIN Table 1
Table 1
id name Payment Amount
=== ======== =====================
1 Jack 10000
2 May 20000
3 Amy 30000
Table 2
id name Payment Amount AccountID
=== ======== ==================== ============
1 Jack 10000 000001
2 Amy 30000 000002
Output that show after execute
id T1name
T2name Payment Amount AccountID
=== ======== ======== ==================== ============
1 Jack Jack 10000 000001
2 May Amy 20000 000002
3 Amy 30000
Output that I expect
id T1name
T2name Payment Amount AccountID
=== ======== ======== ==================== ============
1 Jack Jack 10000 000001
2 May 20000
3 Amy Amy 30000 000002
The table is order by Payment amount.
CREATE TABLE #Table1
([id] varchar(2), [name] varchar(4), [Payment Amount] int)
INSERT INTO #Table1
([id], [name], [Payment Amount])
VALUES
('S1', 'Jack', 10000),
('S2', 'May', 20000),
('S3', 'Amy', 30000)
CREATE TABLE #Table2
([id] varchar(2), [name] varchar(4), [Payment Amount] int)
;
INSERT INTO #Table2
([id], [name], [Payment Amount])
VALUES
('X1', 'Jack', 10000),
('X2', 'Amy', 30000)
select A.id,A.name T1name ,isnull(B.name,'') T2name,A.[Payment Amount] from #Table1 A left join #Table2 B on A.name=B.name
and A.[Payment Amount]=B.[Payment Amount]
output
id T1name T2name Payment Amount
S1 Jack Jack 10000
S2 May 20000
S3 Amy Amy 30000
You should always JOIN with primary key(specifically keys) or with unique key always. otherwise you will get duplicate values. Name column may not be unique and you will get Cartesian product .In your case in order to get your desired results you should join on t1.name=t2.name

SQL retrieval from a table

Sales table
ItemID Date Code
-------------------------------------------------
12345 2019-02-17 1
12345 2019-02-17 2
12345 2019-02-17 3
-------------------------------------------------
12344 2019-02-18 1
12344 2019-02-18 3
12344 2019-02-18 2
-------------------------------------------------
12443 2019-02-19 1
12443 2019-02-19 2
12443 2019-02-19 3
I want to retrieve those item ids from Sales table where Code 2 is updated after code 3. So my query should return 12344 as result... I cannot think of any functions to achieve this as I have limited knowledge on SQL. Can someone please provide me some suggestion on achieving this? Thanks
Here is the query that you are looking for
select sales1.itemId from sales sales1
inner join sales sales2
on sales1.itemId = sales2.itemId
where sales1.date > sales2.date and sales1.code = 2 and sales2.code = 3;
Check if it helps you.
You can try using lag()
select itemid from
(
select sales1.itemId,sales1.code,
sales1.code-lag(code) over(partition by itemid order by dates) as diff
from sales sales1
where code in (2,3)
)A where diff>=1
You can include a column
update_seq_no
Each time you update you can increase the update_seq_no and then you can achieve your requirement you want using the below sql.
alter table sales add (update_seq_no number);
create SEQUENCE IFSQ_UPDATE_SEQNO MINVALUE 1000 MAXVALUE 9999999999999999 INCREMENT BY 1 START WITH 1 NOCYCLE ;
-- for existing rows (just a work around)
BEGIN
for rec in (select rowid row_id,itemid,date from sales where update_Seq_no is null order by 2,3 asc)
loop
update sales set update_Seq_no=IFSQ_UPDATE_SEQNO.NEXTVAL
where rowid=rec.row_id;
commit;
end loop;
end;
--for new rows
insert into sales values(p_itemid,p_date,3,IFSQ_UPDATE_SEQNO.NEXTVAL);
insert into sales values(p_itemid,p_date,2,IFSQ_UPDATE_SEQNO.NEXTVAL);
with sales1 as (select row_num1,a.* from (select rownum row_num1,b.*
from sales b order by update_seq_no asc)a)
select a.*
from sales1 a,sales1 b
where a.row_num1-1=b.row_num1
and a.code=2 and b.code=3
and a.itemid=b.itemid
and a.Date=b.Date;
If there is only one row per itemid and code, then you can simply aggregate:
select itemid
from mytable
group by itemid
having max(case when code = 2 then date end) > max(case when code = 3 then date end);
With your sample data, however, no itemid will be returned, as all codes per itemid have the same date. None comes before the other.