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
Related
I am developing simple inventory system but I am having hard time getting the accurate stock on hand after calculating the 3 quantities from 3 different tables. My goal is to add the sum of receiving_stock + sum of returning_stock - the outgoing_stock. But if outgoing_stock has no data all the records are null.
Here’s my data and query.
receiving_stock
Prod_ID, Qty
123 10
124 10
returning_stock
Prod_ID, Qty
124 10
125 10
outgoing_stock
No Data Yet
Actual Result:
Prod_id, qty
Null 10
Null 20
Null 10
Desired Result:
Prod_id, qty
123 10
124 20
125 10
Query:
Select prod_id, isnull(qty,0)-isnull(sold,0) on-hand
Select prod_id, sum(qty) qty
(
select prod_id,qty
From receiving_stock
Union all
select prod_id,qty
From returning_stock
) Za
Group by prod_id
) Zb
Left join
(
From
Select prod_id, sum(qty) sold
From outgoing_stock
Group by prod_id
) zc
) zd
On
Zb.prod_id=zd.prod_id
You can include the third table in UNION ALL with a negative quantity :
SELECT prod_id,qty
From receiving_stock
UNION ALL
SELECT prod_id,qty
From returning_stock
UNION ALL
SELECT prod_id, -qty
From outgoing_stock
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
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
consider a table
employee id report_year report_quarter sequencenumber quarter1_wage quarter2_wage
101 2015 1 1 1000 0
101 2015 1 2 2000 0
102 2016 2 1 3000 0
102 2016 2 2 0 4000
The Result of the query must be
Total wages
6000
As in 2015 Employee id 101 with Highest sequence number 2 has 2000 comes under quarter1 as report _quarter is indicating it is 1 need to add take this value and add to the
2016 Employee id 102 with highest sequence number 2 has 4000(quarter2_wage)
as report _quarter is indicating it is 2
I really don't understand why you want to sum this way, but ignoring that you are going to be aggregating across quarters and thus the name "Total Wages" is mis-leading, here is how you accomplish that.
--Assign a row number per employee based off the sequence number.
--This will assign 1 to the highest sequence number for each employee
with cte as(
select
*,
ROW_NUMBER() over (partition by [employee id] order by sequencenumber desc) as rn
from yourTable)
--Sum and add the two quarters for all employees where the row number = 1
--Which is the highest sequence
select
sum(quarter1_wage) + sum(quarter2_wage) as TotalWages
from cte
where rn = 1
Have you tried something like this:
WITH cte0 AS(
SELECT 101 AS employeeid,2015 AS report_year,1 AS report_quarter,1 AS sequencenumber,1000 AS quarter1_wage,0 AS quarter2_wage union all
SELECT 101 ,2015 ,1 ,2 ,2000 ,0 union all
SELECT 102 ,2016 ,2 ,1 ,3000 ,0 union all
SELECT 102 ,2016 ,2 ,2 ,0 ,4000
),
cte1 as(
SELECT employeeid,report_year,report_quarter,MAX(sequencenumber) AS maxseqnum
FROM cte0
GROUP BY employeeid,report_year,report_quarter)
SELECT SUM(quarter1_wage+quarter2_wage) AS [Total wages]
FROM cte0 c0
INNER JOIN cte1 c1
ON c0.report_year = c1.report_year AND c0.report_quarter = c1.report_quarter AND c0.employeeid = c1.employeeid AND c0.sequencenumber = c1.maxseqnum
I have a table as below
Id RFrom RTo
.... ....... .....
1 10 14
1 22 25
2 100 102
2 176 180
I want to get all numbers between each RFrom and RTo for each Id. My expected result is as follows
Id NUMS
.... ......
1 10
1 11
1 12
1 13
1 14
1 22
1 23
1 24
1 25
2 100
2 101
2 102
2 176
2 177
2 178
2 179
2 180
Do I have to use cursor to achieve this?
Here is your sample table
SELECT * INTO #TEMP FROM
(
SELECT 1 ID, 10 RFROM, 14 RTO
UNION ALL
SELECT 1, 22, 25
UNION ALL
SELECT 2, 100, 102
UNION ALL
SELECT 2, 176, 180
)TAB
You need to use recursion for each Id to get the result
;WITH CTE AS
(
SELECT ID,RFROM RFROM1,RTO RTO1
FROM #TEMP
UNION ALL
SELECT T.ID,RFROM1+1,RTO1
FROM #TEMP T
JOIN CTE ON CTE.ID = T.ID
WHERE RFROM1 < RTO1
)
SELECT DISTINCT ID,RFROM1 NUMS
FROM CTE
SQL FIDDLE
Another option would be to use a numbers table with a join -- recursion can be time consuming.
There are several options to create a numbers table (I'd recommend creating a permanent one), but here's a temp one created with a common-table-expression:
with numberstable as (
select top 10000 row_number() over(order by t1.number) as number
from master..spt_values t1
cross join master..spt_values t2
)
select yt.id,
nt.number
from yourtable yt
join numberstable nt on nt.number between yt.rfrom and yt.rto
SQL Fiddle Demo
Create a tally table using stacked CTE which will have better performance when compared to recursive CTE
declare #min int
select #min= min(RFrom) from yourtable
;WITH e1(n) AS
(
SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL
SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL
SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1 UNION ALL SELECT 1
), -- 10
e2(n) AS (SELECT 1 FROM e1 CROSS JOIN e1 AS b), -- 10*10
e3(n) AS (SELECT 1 FROM e1 CROSS JOIN e2) -- 10*100
SELECT b.id,
a.n
FROM yourtable b
JOIN (SELECT n = Row_number()OVER (ORDER BY n)+ #min-1
FROM e3)a
ON a.n BETWEEN b.RFrom AND b.RTo
ORDER BY n;
Check here for info