How to express this query in SQL Server 2008 - sql

I have table called Reporting with following columns
OutletId CampaignId ItemId Qty
10 1 Item1 12
10 1 Item2 13
10 1 Item3 14
20 2 Item4 10
20 2 Item5 11
20 2 Item6 12
20 2 Item7 8
Now I want to retrieve the data in this format
when user select campaignId =1
OutletId CampaignId Item1 Item2 Item3
10 1 12 13 14
when user select CampaignId=2
OutletId CampaignId Item4 Item5 Item6 Item7
20 2 10 11 12 8
Here Items for campaign are not fixed

I think it is efficient in this way:
SELECT *
FROM
(
SELECT OutletId, CampaignId, ItemId, Qty
FROM Reporting) AS p
PIVOT
(
SUM(Qty)
FOR ItemId IN (SELECT ItemId FROM Reporting WHERE campaignId =1)
) as pvt
Comment: Here campaignId =1 or campaignId =2 or campaignId =... whatever u want

A possible solution would be:
SELECT *
FROM
(
SELECT OutletId, CampaignId,ItemId, Qty
FROM test) AS p
PIVOT
(
SUM(Qty)
FOR ItemId IN (Item1,Item2,Item3,Item4)
) as pvt
But obviously, as commented before is not very efficient because you don't always know the Items... you either redesign your table or if using PIVOT you can build a dynamic sql building pivot items previously.

Related

Access SQL multiple tables result dependent on result

I'm a SQL newbie and need some help with linking 3 tables in Access. Each order has differnt size type from SIZE_TABLE. I need a SQL statement that produces below query result:
Item
Color
Size
Size*Qty
UPCCode
Thank you!
ORDER_TABLE:
ID
ProductID
Color
SizeType
Size1Qty
Size2Qty
Size3Qty
Size4Qty
Size5Qty
1
Item1
Black
A
0
20
20
10
0
2
Item2
Red
B
15
25
25
15
5
3
Item3
White
C
10
15
0
0
0
4
Item4
Yellow
D
20
0
0
0
0
...
...
...
...
...
...
...
...
...
SIZE_TABLE:
ID
SizeType
Size
Size_Num
1
A
XS
Size1
2
A
S
Size2
3
A
M
Size3
4
A
X
Size4
5
A
XL
Size5
6
B
30
Size1
7
B
32
Size2
8
B
34
Size3
9
B
36
Size4
10
B
38
Size5
11
C
SM
Size1
12
C
ML
Size2
13
D
OS
Size1
BARCODE_TABLE:
ID
ProductID
Color
Price
Size
UPCCode
1
Item1
Black
$99
XS
7229473512
2
Item2
Red
$59
30
7229475516
3
Item3
White
$69
OS
7229474902
4
Item4
Yellow
$49
XL
7229474902
...
...
...
...
...
...
Use UNION query to rearrange Order_Table to normalized structure then use that query in subsequent query to join with other tables
SELECT ID, ProductID, Color, SizeType, Size1Qty AS Qty, "Size1" AS Size FROM Order_Table
UNION SELECT ID, ProductID, Color, SizeType, Size2Qty, "Size2" FROM Order_Table
UNION SELECT ID, ProductID, Color, SizeType, Size3Qty, "Size3" FROM Order_Table
UNION SELECT ID, ProductID, Color, SizeType, Size4Qty, "Size4" FROM Order_Table
UNION SELECT ID, ProductID, Color, SizeType, Size5Qty, "Size5" FROM Order_Table;
To avoid UNION query, normalize data structure. Create a dependent table that relates to Order_Table. Call it OrderDetails_Table.
ID | OrderID_FK | ProductID | Qty
Order_Table should have fields for OrderID, CustID, OrderDate.

Using sql to recursively generate values depending on keys and column values

I have a table like this:
store
item
value
store1
item1
2
store1
item2
3
I want to use it to create the following table:
store
item
value
store1
item1
0
store1
item1
1
store1
item1
2
store1
item2
0
store1
item2
1
store1
item2
2
store1
item2
3
I'm aware that I can do with recursive n(n) as (select 0 n union all select n + 1 from n limit 40) and then later a cross join if the upper limit was constant (40) but in my case, it changes by (store, item). I was wondering if this can be done in SQL or if it is better to figure it out in python. Thanks.
You can use a recursive CTE. The syntax is something like this:
with recursive cte(store, item, value, n) as (
select store, item, value, 0
from t
union all
select store, item, value, n + 1
from cte
where n < value
)
select store, item, n as value
from cte;
The exact syntax for recursive CTEs varies, depending on the database. This appears to be similar to the code you have in your question.
Here is a db<>fiddle.

complex paratition sum in postgresql

I have tables as follow:
A deliveries
delveryid clientid deliverydate
1 10 2015-01-01
2 10 2015-02-02
3 11 2015-04-08
B items in deliveris
itemid deliveryid qty status
70 1 5 1
70 1 8 2
70 2 10 1
72 1 12 1
70 3 100 1
I need to add a column to my query that gives me the qty of each part in other deliveris of the same client.
meaning that for given data of client 10 and delivery id 1 I need to show:
itemid qty status qtyOther
70 5 1 10 //itemid 70 exists in delivery 2
70 8 2 10 //itemid 70 exists in delivery 2
72 12 1 0 //itemid 72 doesn't exists in other delivery of client 11
Since I need to add qtyOther to my existing qry i'm trying to avoid using Group By as it's a huge query and if I use SUM in select I will have to group by all items in select.
This is what I have so far:
Select ....., coalesce( SUM(a.qty) OVER (PARTITION BY a.itemid) ,0) AS qtyOther
FROM B b
LEFT JOIN A a USING
LEFT JOIN (other tables)
WHERE clientid=10 ....
This query gives me the total sum of qty per itemid for specific clientid, regardless of which delivery it is. How do I change it so it will consider the delivryid? I need something like:
coalesce( SUM(a.qty) OVER (PARTITION BY a.itemid) FROM B where deliveryid<>b.deliveryid ,0) AS qtyOther
Any suggestions how to do that?
Note: I can NOT change the condition in WHERE.
I think you just want to subtract out the total for the current delivery:
Select .....,
(coalesce( SUM(a.qty) OVER (PARTITION BY a.itemid), 0) -
coalesce( SUM(a.qty) OVER (PARTITION BY a.itemid, a.deliveryid), 0)
) as qtyOther

Aggregate function within table I'm creating

I have a dataset where I have an ItemID and then quantity sold at each price like this:
ItemID | Quantity | Price
ABC 10 14.50
ABC 4 14.25
DEF 32 22.41
ABC 24 14.10
GHI 8 8.50
GHI 12 8.60
DEF 2 22.30
Every entry has a unique combination of ItemID and Price. I would like to add a fourth column that has the total quantity sold for that ItemID. So it would look like this for the above table:
ItemID | Quantity | Price | TotalQ
ABC 10 14.50 38
ABC 4 14.25 38
DEF 32 22.41 34
ABC 24 14.10 38
GHI 8 8.50 20
GHI 12 8.60 20
DEF 2 22.30 34
I can't seem to do this without performing an aggregate function on an aggregate function, which obviously gives an error. How would I go about accomplishing this?
I'm using SQL Server 2008.
Please try:
SELECT
*,
SUM(Quantity) OVER(PARTITION BY ItemID) TotalQ
FROM
YourTable
Try this code
select a.ItemID,a.Quantity,a.Price,x.Total form table_name a
left outer join
(select sum(Quantity) Total, ItemID from table_name group by ItemID)x
on x.ItemID = a.ItemID
If you need this just in query you can write something like this:
;WITH CTE_Total AS
(
SELECT ItemID, SUM(Quantity) as TotalQ
FROM YourTable
GROUP BY ItemID
)
SELECT t.*, c.TotalQ
FROM YourTable t
LEFT JOIN CTE_Total c on t.ItemID = c.ItemID
SQLFiddle DEMO
But, if you want to have automated computed column in your table, first you need to create function that does the calculation:
CREATE FUNCTION dbo.fn_YourTableTotalQ (#ItemID VARCHAR(3))
RETURNS Int
AS
BEGIN
DECLARE #toRet INT
SELECT #toRet = COALESCE(SUM(Quantity),0)
FROM YourTable WHERE ItemID = #ItemID
RETURN #toRet
END
... and then add your new column as computed using this function:
ALTER TABLE YourTable
ADD TotalQ AS dbo.fn_YourTableTotalQ(ItemID)
SQLFiddle DEMO

Make a recursive function in SQL Server 2005

cat_id prod_name parent_cat_id
------ ---------- ------------
1 prod_1 2
2 prod_2 5
3 prod_3 1
4 prod_4 3
5 prod_5 7
6 prod_6 5
In a recursive function, make a table and by using these, if cat_id = 1 and parent_cat_id = 1 take that product name and if that product category id and parent category id is same then take that record also..
ANS IS LIKE :::
1 prod_1 2
2 prod_2 5
5 prod_5 7
WITH rows AS
(
SELECT cat_id, prod_name, parent_cat_id
FROM mytable
WHERE cat_id = 1
UNION ALL
SELECT m.cat_id, m.prod_name, m.parent_cat_id
FROM mytable m
JOIN rows r
ON r.parent_cat_id = m.cat_id
)
SELECT *
FROM rows