Query for replacing data if the value is not number - sql

I have a similar problem like this thread but is bit different what it required
https://community.oracle.com/thread/4132183
I have the following table:
Table1:
ID empID employeeactive dtefrom dateto mgrid
1 123 1 1/10/2016 113
2 213 0 1/20/2015 1/20/2016 323
3 213 1 1/20/2016 423
4 312 0 1/05/2016 1/30/2017 523
5 512 1 1/30/2017 623
6 812 1 2/30/2017 6543
Table2:
empID emplyactive supid
123 1 -
213 1 -
312 1 -
512 0 -
612 1 -
712 1 -
812 1 872
912 0 222
I have this table instead of - i want to replace with mgrid in table 1.. and table2 have extra data which is not in table1 so i have to ignore the extra data if supid '-' and also want to have emplyactive =1 but some of the emplyactive=1 table 1 has multiple mgr id ...
so I tried this one
select empid , decode(supid,'-',mgrid,supid) from table2,table1 where
empid(+) = empid and emplyactive =1 and employeeactive=1
so I am getthing how to solve this please help me out thank you .. if some thing like and exists will work thanks in advance.
This is what I am trying to insert in a package body oracle.
This is how the output looks like:
empID emplyactive supid
123 1 113
213 1 423
812 1 872

select a.empid, a.emplyactive, max(a.supid) supid
from (
select * from #table2
union
select empid, employeeactive, mgrid from #table1)a
left join #table1 b on a.empid=b.empid and employeeactive=1
join #table2 c on a.empid=c.empid and c.emplyactive=1
where a.emplyactive=1
and a.supid<>0
group by a.empid, a.emplyactive

Related

Joins and/or Sub queries or Ranking functions

I have a table as follows:
Order_ID
Ship_num
Item_code
Qty_to_pick
Qty_picked
Pick_date
1111
1
1
3000
0
Null
1111
1
2
2995
1965
2021-05-12
1111
2
1
3000
3000
2021-06-24
1111
2
2
1030
0
Null
1111
3
2
1030
1030
2021-08-23
2222
1
3
270
62
2021-03-18
2222
1
4
432
0
Null
2222
2
3
208
0
Null
2222
2
4
432
200
2021-05-21
2222
3
3
208
208
2021-08-23
2222
3
4
232
200
2021-08-25
From this table,
I only want to show the rows that has the latest ship_num information, not the latest pick_date information (I was directed to a question like this that needed to return the rows with the latest entry time, I am not looking for that) for an order i.e., I want it as follows
Order_ID
Ship_num
Item_code
Qty_to_pick
Qty_picked
Pick_date
1111
3
2
1030
1030
2021-08-23
2222
3
3
208
208
2021-08-23
2222
3
4
232
200
2021-08-25
I tried the following query,
select order_id, max(ship_num), item_code, qty_to_pick, qty_picked, pick_date
from table1
group by order_id, item_code, qty_to_pick, qty_picked, pick_date
Any help would be appreciated.
Thanks in advance.
Using max(ship_num) is a good idea, but you should use the analytic version (with an OVER clause).
select *
from
(
select t.*, max(ship_num) over (partition by order_id) as orders_max_ship_num
from table1 t1
) with_max
where ship_num = orders_max_ship_num
order by order_id, item_code;
You can get this using the DENSE_RANK().
Query
;with cte as (
select rnk = dense_rank()
over (Partition by order_id order by ship_num desc)
, *
from table_name
)
Select *
from cte
Where rnk =1;

calculate Count and Sum from two different table with group by without using inner query

I have two table first A having column id,phone_number,refer_amount
and second B having column phone_number,transaction_amount
now i want sum() of refer_amount and transaction_amount and count() of phone_number from both table using group by phone_number without using inner query
Table A
phone_number refer_amount
123 50
456 80
789 90
123 90
123 80
123 20
456 20
456 79
456 49
123 49
Table B
phone_number transaction_amount
123 50
123 51
123 79
456 22
456 11
456 78
456 66
456 88
456 88
456 66
789 66
789 23
789 78
789 46
i have tried following query but it gives me wrong output:
SELECT a.phone_number,COUNT(a.phone_number) AS refer_count,SUM(a.refer_amount) AS refer_amount,b.phone_number,COUNT(b.phone_number) AS toal_count,SUM(b.transaction_amount) AS transaction_amount FROM dbo.A AS a,dbo.B AS b WHERE a.phone_number=b.phone_number GROUP BY a.phone_number,b.phone_number
output (wrong):
phone_number refer_count refer_amount phone_number transaction_count transaction_amount
123 15 867 123 15 900
456 28 1596 456 28 1676
789 5 450 789 5 291
output (That I want):
phone_number refer_count refer_amount phone_number transaction_count transaction_amount
123 5 289 123 3 180
456 4 228 456 7 419
789 1 90 789 5 291
I would do the aggregations on the B table in a separate subquery, and then join to it:
SELECT
a.phone_number,
COUNT(a.phone_number) AS a_cnt,
SUM(a.refer_amount) AS a_sum,
COALESCE(b.b_cnt, 0) AS b_cnt,
COALESCE(b.b_sum, 0) AS b_sum
FROM A a
LEFT JOIN
(
SELECT
phone_number,
COUNT(*) AS b_cnt,
SUM(transaction_amount) AS b_sum
FROM B
GROUP BY phone_number
) b
ON a.phone_number = b.phone_number;
One major potential issue with your current approach is that the join could result in duplicate counting, as a given phone_number record in the A table gets replicated due to the join.
Speaking of joins, note that above I use an explicit join, rather than the implicit one you were using. In general, you should not put commas into the FROM clause.
This can help. You don't need sum(b.phone_number) when checking for a.phone_number = b.phone_number. Distinct is needed for phone number as there are two columns to consider.
For group by, anything not in aggregate function needs to be in group by function.
select a.phone_number, count(distinct a.phone_number), sum(a.refer_amount),
sum (b.transaction_amount)
from A as a, B as b
where a.phone_number=b.phone_number
group by a.phone_number

SQL transpose data

I need to transpose data that looks like the following. I don't need to use any aggregate functions, just want to transpose columns to rows.
Current view:
Name | Code1 | Code2 | Code3 | Pct1 | Pct2 | Pct3 | Amt1 | Amt2 | Amt3
Name1 123 124 125 50 25 25 1000 1500 1555
Name2 123 124 125 50 25 25 1222 1520 1600
What I Need:
AccountName | Code# | Pct | Amt
Name1 123 50 1000
Name1 124 25 1500
Name1 125 25 1555
Name2 123 50 1222
Name2 124 25 1520
Name2 125 25 1600
if this is possible, could you also include where I would place my joins if I need to use data in a different table?
I'm using SQL Server Management Studio 2014 and I don't have the permission to create tables
This is a neat trick using table valued expression
SELECT [Name], ca.*
From myTable
CROSS APPLY (Values
(Code1, Pct1, Amt1),
(Code2, Pct2, Amt2),
(Code3, Pct3, Amt3)
) ca([Code#], [Pct], [Amt])
select
Name,
case n when 1 then Code1 when 2 then Code2 when 3 then Code3 end as Code,
case n when 1 then Pct1 when 2 then Pct2 when 3 then Pct3 end as Pct,
case n when 1 then Amt1 when 2 then Amt2 when 3 then Amt3 end as Amt
from T cross join (values (1), (2), (3)) multiplier(n)
The basic idea is to triplicate the rows and then use case to pick out the correct values.

List the last two records for each id

Good Afternoon!
I'm having trouble list the last two records each idmicro
Ex:
idhist idmicro idother room unit Dtmov
100 1102 0 8 coa 2009-10-23 10:40:00.000
101 1102 0 1 coa 2009-10-28 10:40:00.000
102 1102 0 2 dib 2008-10-24 10:40:00.000
103 1201 0 6 diraf 2008-10-23 10:40:00.000
104 1201 0 7 diraf 2009-10-21 10:40:00.000
105 1201 0 4 dimel 2008-10-22 10:40:00.000
Would look like this:
ex:
result
idhist idmicro idoutros room unit Dtmov
101 1102 0 1 coa 2009-10-28 10:40:00.000
102 1102 0 2 dib 2008-10-24 10:40:00.000
103 1201 0 6 diraf 2008-10-22 10:40:00.000
104 1201 0 7 diraf 2009-10-21 10:40:00.000
I'm starting to delve into SQL and am having trouble finding this solution
Sorry
Thank you.
EDIT: I am using SQL server, and I made no query.
Yes! is based on the date and time
You can do the same thing with an imbricated SELECT statement.
SELECT *
FROM (
SELECT row_number() OVER (
PARTITION BY idmicro ORDER BY idhist
) AS ind
,*
FROM data
) AS initialResultSet
WHERE initialResultSet.ind < 3
Here is a sample SQLFiddle with how this query works.
WITH etc
AS (
SELECT *
,row_number() OVER (
PARTITION BY idmicro ORDER BY idhist
) AS r
,count() OVER (
PARTITION BY idmicro ORDER BY idhist
) cfrom TABLE
)
SELECT *
FROM etc
WHERE r > c - 2
Use row_number and over partition
SELECT *
FROM (
SELECT *, row_number() OVER (PARTITION BY idmicro ORDER BY idhist desc) AS rownum
FROM data
) AS initialResultSet
WHERE initialResultSet.rownum<=2

Update Table column with values for other column

I have a table along these lines:
Client | Date | Value 1 | Value 2 |
1 2013-11-08 159 159
1 2013-11-09 254 254
1 2013-12-05 512 512
1 2014-01-02 1200 1200
2 2013-11-10 189 189
2 2013-11-15 289 289
2 2013-12-22 585 585
2 2014-01-06 1650 1650
I need to update the table in SQL to look like this:
Client | Date | Value 1 | Value 2 |
1 2013-11-08 159 1200
1 2013-11-09 254 1200
1 2013-12-05 512 1200
1 2014-01-02 1200 1200
2 2013-11-10 189 1650
2 2013-11-15 289 1650
2 2013-12-22 585 1650
2 2014-01-06 1650 1650
The idea is that for each Client, Value 2 will become Value 1 where Date is most recent.
In SQL Server the best best thing to use is CTE with UPDATE statement. The query below demonstrates the syntax for what you need to do. All you have to do is substitute your table name and columns names.
;WITH MyUpdate
AS ( SELECT ClientId
,Value1
,ROW_NUMBER() OVER ( PARTITION BY ClientId ORDER BY MyDate DESC ) AS RowNum
FROM MyTable)
UPDATE MyTable
SET MyTable.Value2 = MyUpdate.Value1
FROM MyTable
INNER JOIN MyUpdate
ON MyUpdate.ClientID = MyTable.ClientID
AND RowNum = 1
Try this:
UPDATE TABLE1 T2 SET Value2 =
(SELECT T1.Value2 FROM TABLE1 T1 WHERE T1.Client = T2.Client AND
T1.Date = (SELECT MAX(T3.Date) FROM TABLE1 T3
WHERE T2.Client = T3.Client GROUP BY Client));
ORACLE