Table: DataTable1
ID SKU QTY
-----------------------
1 AAAA 1
2 BBBB 1
3 CCCC 1
4 CCCC 1
Table: DataTable2
ID assign_id SKU
-----------------------------
123 99 AAAA
124 99 CCCC
Is there any way to get result like this?
Thank you in advance.
ID SKU QTY AssignID
-----------------------------------
1 AAAA 1 99
2 BBBB 1 NULL
3 CCCC 1 99
4 CCCC 1 NULL
Not sure, but probably this is what you need
with DataTable1(ID , SKU , QTY ) as(
select 1 ,'AAAA', 1 union all
select 2 ,'BBBB', 1 union all
select 3 ,'CCCC', 1 union all
select 4 ,'CCCC', 1
),
DataTable2(ID , assign_id , SKU) as (
select 123, 99 ,'AAA' union all
select 124 , 99 ,'CCC'
)
select t.ID, t.SKU, t.QTY, case when rn = 1 then assign_id else null end as assign_id
from (
select DataTable1.*, DataTable2.assign_id, row_number() over(partition by DataTable1.SKU order by DataTable1.ID) as rn
from DataTable1
left join DataTable2
on DataTable1.SKU like concat(DataTable2.SKU, '%')
) t
Related
I have a non-normalized table with several columns. I would like to return all columns that have a positive number along with a negative number of the same value.
Example:
ID | Value
-------------
1 | 10
1 | -10
3 | 15
3 | 15
4 | -1
5 | 4
Current Output:
ID | Values
-------------
1 | 10
1 | -10
3 | 15
3 | 15
Desired Output:
ID | Value
-------------
1 | 10
1 | -10
I have made a windows function as seen below that will select absolute values that are the same, but this includes pairs where there are a positive number.
select Count(*) Over (Partition By DVN, [Tran Date], [Reference Number],Description,Vendor, Abs([Maintenance Expense])) As cnt , *
From WorkTemp.dbo.Customer2700Combine
Where [Maintenance Expense] Is Not Null
Order By 1 Desc,DVN, [Tran Date], [Reference Number],Description,Vendor, Abs([NonRental Total])
Not sure if your requirement is by [ID], looking at your example, description and desired output, this is how I would do it:
DROP TABLE IF EXISTS #sopg;
SELECT [ID],
[VALUE]
INTO #sopg
FROM
(
SELECT 1 AS ID,
10 AS VALUE
UNION
SELECT 1 AS ID,
-10 AS VALUE
UNION
SELECT 3 AS ID,
15 AS VALUE
UNION
SELECT 3 AS ID,
15 AS VALUE
UNION
SELECT 4 AS ID,
-1 AS VALUE
UNION
SELECT 5 AS ID,
4 AS VALUE
) x;
-- Assuming that one ID can only have maximum 2 rows (like your example above) and want this by ID
SELECT s.[ID],
s.[VALUE]
FROM #sopg s
INNER JOIN
(
SELECT ID,
SUM(VALUE) SumZero
FROM #sopg
GROUP BY ID
HAVING SUM(VALUE) = 0
) SumZero ON SumZero.ID = s.ID
-- Another way, assuming that ID can have more than 2 rows and different values
DROP TABLE IF EXISTS #sopg2;
SELECT [ID],
[VALUE]
INTO #sopg2
FROM
(
SELECT 1 AS ID,
10 AS VALUE
UNION
SELECT 1 AS ID,
-10 AS VALUE
UNION
SELECT 1 AS ID,
-9 AS VALUE
UNION
SELECT 3 AS ID,
15 AS VALUE
UNION
SELECT 3 AS ID,
15 AS VALUE
UNION
SELECT 4 AS ID,
-1 AS VALUE
UNION
SELECT 5 AS ID,
4 AS VALUE
) x
SELECT a.[ID],
a.[VALUE]
FROM #sopg2 a
INNER JOIN #sopg b ON b.ID = a.ID AND a.VALUE = -b.VALUE
I have 2 tables
TableA: Main table with 1 record for each Field called ID
TableB: Can contain multiple record for field called ID
I want to select everything based on ID from TableA and TableB in 1 line for the end result
Example
Sample Records
From TableA
ID Name Address
--- ---- ----------
1 Jack 123 blahST
2 John 234 blahAVE
321 Sam 2123 blahWay
From TableB
ID AccNO
-- -------------
1 12345
1 345345
1 443453
2 99999
3 88888
3 77777
End Result should be like
Select TableA.ID,
TableA.Name,
TableA.Address,
TableB.ID,
TableB.AccNO1,
TableB.AccNO2, --if it exist
TableB.AccNO3, --if it exist
TableB.AccNO4, --if it exist MAX
From TableA Full Outer Join TableB on TableB.ID = TableA.ID
TableA.ID TableA.Name TableA.Address TableB.ID TableB.AccNO TableB.AccNO2 TableB.AccNo3,TableB.AccNo4
--------- ----------- -------------- --------- ------------ ------------- ------------- -------------
1 Jack 123 Blahst 1 12345 345345 443453
2 John 234 BlahAVE 2 99999
3 Sam 2123 Blahway 3 88888 7777777
Here are a couple of ways of doing it - one using the PIVOT keyword available in 11g and above, the other using the old-style pivot using MAX() and group by.
Method 1:
with tablea as (select 1 id, 'Jack' name, '123 blahST' address from dual union all
select 2 id, 'John' name, '234 blahAVE' address from dual union all
select 3 id, 'Sam' name, '2123 blahWay' address from dual),
tableb as (select 1 id, 12345 accno from dual union all
select 1 id, 345345 accno from dual union all
select 1 id, 443453 accno from dual union all
select 2 id, 99999 accno from dual union all
select 3 id, 88888 accno from dual union all
select 3 id, 77777 accno from dual),
b_res as (select *
from (select id,
accno,
row_number() over (partition by id order by accno) rn
from tableb)
pivot (max(accno)
for rn in (1 as accno1,
2 as accno2,
3 as accno3,
4 as accno4,
5 as accno5)))
select ta.id ta_id,
ta.name ta_name,
ta.address ta_address,
tb.id tb_id,
tb.accno1 tb_accno1,
tb.accno2 tb_accno2,
tb.accno3 tb_accno3,
tb.accno4 tb_accno4,
tb.accno5 tb_accno5
from tablea ta
inner join b_res tb on ta.id = tb.id;
TA_ID TA_NAME TA_ADDRESS TB_ID TB_ACCNO1 TB_ACCNO2 TB_ACCNO3 TB_ACCNO4 TB_ACCNO5
---------- ------- ------------ ---------- ---------- ---------- ---------- ---------- ----------
1 Jack 123 blahST 1 12345 345345 443453
2 John 234 blahAVE 2 99999
3 Sam 2123 blahWay 3 77777 88888
Method 2:
with tablea as (select 1 id, 'Jack' name, '123 blahST' address from dual union all
select 2 id, 'John' name, '234 blahAVE' address from dual union all
select 3 id, 'Sam' name, '2123 blahWay' address from dual),
tableb as (select 1 id, 12345 accno from dual union all
select 1 id, 345345 accno from dual union all
select 1 id, 443453 accno from dual union all
select 2 id, 99999 accno from dual union all
select 3 id, 88888 accno from dual union all
select 3 id, 77777 accno from dual),
b_res as (select id,
max(case when rn = 1 then accno end) accno1,
max(case when rn = 2 then accno end) accno2,
max(case when rn = 3 then accno end) accno3,
max(case when rn = 4 then accno end) accno4,
max(case when rn = 5 then accno end) accno5
from (select id,
accno,
row_number() over (partition by id order by accno) rn
from tableb)
group by id)
select ta.id ta_id,
ta.name ta_name,
ta.address ta_address,
tb.id tb_id,
tb.accno1 tb_accno1,
tb.accno2 tb_accno2,
tb.accno3 tb_accno3,
tb.accno4 tb_accno4,
tb.accno5 tb_accno5
from tablea ta
inner join b_res tb on ta.id = tb.id;
TA_ID TA_NAME TA_ADDRESS TB_ID TB_ACCNO1 TB_ACCNO2 TB_ACCNO3 TB_ACCNO4 TB_ACCNO5
---------- ------- ------------ ---------- ---------- ---------- ---------- ---------- ----------
1 Jack 123 blahST 1 12345 345345 443453
2 John 234 blahAVE 2 99999
3 Sam 2123 blahWay 3 77777 88888
I have the following set of data (sample given)
ID Status Code Type ModDate
1234 1 1 AB 1995-04-01
1234 1 1 CD 1998-08-31
1234 1 1 AB 2003-08-31
1234 1 NULL AB 2008-11-08
1234 1 2 AB 2013-11-09
1234 1 1 EF 2013-11-18
...
As these data has to be viewed on some sort of timeline, I want to read just the following from the database, as only the Type changes are of interest:
ID Status Code Type ModDate
1234 1 1 AB 1995-04-01
1234 1 1 CD 1998-08-31
1234 1 1 AB 2003-08-31
1234 1 1 EF 2013-11-18
...
How can this be done? I tried to partition the data and give some row numbers, but it gives me headaches becuase the Type is grouped.
SELECT
ID, Status, Code, Type, ModDate,
MIN(ModDate) OVER (PARTITION BY ID, Type) MinModDate,
MAX(ModDate) OVER (PARTITION BY ID, Type) MaxModDate,
ROW_NUMBER() OVER (PARTITION BY ID, Type ORDER BY ModDate) RowNumber
FROM Data
Output:
ID Status Code Type ModDate MinModDate MaxModDate RowNumber
1234 1 1 AB 1995-04-01 1995-04-01 2013-11-09 1
1234 1 1 CD 1998-08-31 1998-08-31 1998-08-31 1
1234 1 1 AB 2003-08-31 1995-04-01 2013-11-09 2
1234 1 NULL AB 2008-11-08 1995-04-01 2013-11-09 3
1234 1 2 AB 2013-11-09 1995-04-01 2013-11-09 4
1234 1 1 EF 2013-11-18 2013-11-18 2013-11-18 1
...
Output expected:
ID Status Code Type ModDate MinModDate MaxModDate RowNumber
1234 1 1 AB 1995-04-01 1995-04-01 2013-11-09 1
1234 1 1 CD 1998-08-31 1998-08-31 1998-08-31 1
1234 1 1 AB 2003-08-31 1995-04-01 2013-11-09 1
1234 1 NULL AB 2008-11-08 1995-04-01 2013-11-09 2
1234 1 2 AB 2013-11-09 1995-04-01 2013-11-09 3
1234 1 1 EF 2013-11-18 2013-11-18 2013-11-18 1
...
Can this be achieved easily without using cursors?
since you use 2012 then this should work:
SELECT ID, Status, Code, Type, ModDate FROM
(
SELECT
ID, Status, Code, Type, ModDate,
lag(type,1) OVER (ORDER BY ID, moddate) prevtype
FROM data
)t WHERE type<>ISNULL(prevtype,'')
Partitioning the data is what you want, you just need to do it by Type, since that the only changes of interest. You also need to add the ROW_NUMBER() function in order to filter the rows you want. Here's an updated query.
;WITH cte AS
(
SELECT ID, [Status], Code, [Type], ModDate
,rn = ROW_NUMBER() OVER (PARTITION BY ModDate ORDER BY ModDate)
FROM #data
)
SELECT ID, [Status], Code, [Type], ModDate
FROM cte
WHERE rn = 1
ORDER BY ModDate, [Type]
If I understood correctly, you just need to wrap your original SQL:
SELECT ID, Status, Code, Type, ModDate FROM
(
SELECT
ID, Status, Code, Type, ModDate,
MIN(ModDate) OVER (PARTITION BY ID, Type) MinModDate,
MAX(ModDate) OVER (PARTITION BY ID, Type) MaxModDate,
ROW_NUMBER() OVER (PARTITION BY ID, Type ORDER BY ModDate) RowNumber
FROM Data
) t
WHERE ModDate=MinModDate
I have a table with id, sname, attendance columns like
id sname attendance month
1 xyz p 12
2 asd p 12
3 qwe L 12
4 tyy A 12
I want to reinsert id and sname for next month's attendance for every month.
Now I want to reinsert data for month 1 with AB in Attendance column like this:
id sname attendance month
1 xyz p 12
2 asd p 12
3 qwe L 12
4 tyy A 12
1 xyz ab 1
2 asd ab 1
3 qwe ab 1
4 tyy ab 1
If I've got it right:
INSERT INTO t (id,sname,attendance,month)
SELECT id,sname,'ab',(month%12)+1 from t
Try this
INSERT INTO your_table (id,sname,attendance,month)
SELECT T.id, T.sname, T.attendance, M.m
FROM (SELECT 1 m UNION SELECT 2 UNION SELECT 3 UNION SELECT 4 UNION SELECT 5 UNION SELECT 6 UNION SELECT 7 UNION SELECT 8 UNION SELECT 9 UNION SELECT 10 UNION SELECT 11 UNION SELECT 12) AS M
CROSS JOIN your_table T
WHERE NOT EXISTS (SELECT * FROM your_table WHERE m=M.m)
And better don't use reserved words like MONTH for names of tables, columns and other objects.
My database record is as below:-
cartid orderid foodid qty
==============================
92 107 5 1
93 107 5 1
94 107 5 1
95 107 11 1
96 107 5 1
97 108 5 1
Can it be arrange into this form?
Assume that the max sum(qty)=3
foodid sum(qty)
=================
5 3
11 1
5 2
You look like you are trying to sum contiguous ranges (islands) of the same foodid ordered by cartid?
;with cart as
(
SELECT 92 AS cartid,107 AS orderid,5 AS foodid, 1 AS qty UNION ALL
SELECT 93,107,5, 1 UNION ALL
SELECT 94,107,5, 1 UNION ALL
SELECT 95,107,11,1 UNION ALL
SELECT 96,107,5, 1 UNION ALL
SELECT 97,108,5, 1
),
NumberedCart As
(
SELECT cartid,foodid,qty,
ROW_NUMBER() OVER (ORDER BY cartid)-
ROW_NUMBER() OVER (PARTITION BY foodid ORDER BY cartid) AS G
FROM cart
)
SELECT foodid, SUM(qty) AS [sum(qty)]
FROM NumberedCart
GROUP BY foodid,G
ORDER BY MIN(cartid)
Returns
foodid sum(qty)
----------- -----------
5 3
11 1
5 2
I'm not sure what you mean by Max Sum(qty)=3...
But here is some SQL to get you started:
SELECT foodid
, SUM(qty)
FROM YourTableName
GROUP BY foodid