Complex SQL Query - i found no answer :( - sql

i've have a MS-SQL table which contains the following columns:
ID, SKU, StockID, StockQTY
The columns/rows are filled like:
ID
SKU
StockID
StockQTY
1
1111
1
12
2
1111
13
20
3
2222
1
0
4
2222
13
5
5
3333
1
0
6
3333
13
4
Now i need a SQL query which show all SKU (second column) which have a StockQTY = 0 in StockID = 1 AND a StockQTY > 1 in StockID 13. All other rows should not be shown (in this example row 1 and 2 should not be shown in the result).
Have anyone an idea how to realize this?

You can use a correlated subquery to test for skus that have 0 qty in StockID 1 and then just keep anything that has a qty greater than 1 in your StockID 13.
SELECT SKU
FROM yourtable yt
WHERE Stockid = 13
AND NOT EXISTS (SELECT 1 FROM yourtable WHERE StockID = 1 AND yt.SKU = SKU)
HAVING Sum(StockQty) > 1

Try something like:
SELECT SKU FROM yourTableName WHERE
(StockQTY = 0 AND StockID = 1) OR (StockQTY > 1 AND StockID = 13);
To pull data obviously it is a SELECT statement, you could use * instead of SKU if you want ALL the data instead of just the SKU number. Exchange yourTableName with the actual table name. The WHERE clause is the meat of your question. This use of OR and AND can be confusing. We have 2 cases we are testing. One where the stock is 0 but the ID is 1, but we use the OR so that regardless if that is found or not, we can then do the next part where the StockQTY is 1 and the StockID is 13. You need the and for both conditions in the own case, and you want OR so that either of these two cases will pull up.

Related

Calculate product of column values on the basis of other column in SQL Server

I have a table
Tid Did value
------------------
1 123 100
1 234 200
2 123 323
2 234 233
All tids have dids as 123 and 234. So for every tid having dids 123 and 234 I want the product of corresponding values
The output table will be
Tid Product
------------------
1 20000 (product of 100 and 200)
2 75259 (product of 323 and 233)
Any help?
select tid,
min(case when did = 123 then value end)
* min(case when did = 234 then value end) product
from my_table
group by tid
To get the data for multiple rows combined (based on tid) you use GROUP BY.
Because you're grouping by tid, you have to use an aggregate function to do anything with other values from the individual rows. If implied assumptions hold (exactly 1 row matching each did for each tid) then it doesn't matter much what aggregate function you use; min is as good as anything.
Within the aggregation, you use CASE logic to select value for the required did (and NULL for all other rows in the tid group).
Then just do the math.
You can use some arithmetic to get the product per tid.
select tid,exp(sum(log(value))) as prod
from t
group by tid
To do this only for tid's having did values 123 and 234, use
select tid,exp(sum(log(value))) as prod
from t
group by tid
having count(distinct case when did in (123,234) then did end) = 2
Here's a Rexster solution, based on good work of #gbn here
SELECT
Tid,
CASE
WHEN MinVal = 0 THEN 0
WHEN Neg % 2 = 1 THEN -1 * EXP(ABSMult)
ELSE EXP(ABSMult)
END
FROM
(
SELECT
Tid,
SUM(LOG(ABS(NULLIF(value, 0)))) AS ABSMult,
SUM(SIGN(CASE WHEN value < 0 THEN 1 ELSE 0 END)) AS Neg,
MIN(ABS(value)) AS MinVal
FROM
t
GROUP BY
Tid
) t2

How to use the SUM function on a specific table two times and then make a deduction

Is it possible in the same SQL query to use the SUM function for different occasions;
For example, lets use the below SQL table called 'TEMPTABLE'
On the table you can see that the item with ITEM_ID=001 appears three times. On the first two times appears with the OCCASION 1 and on the last one with the OCCASION 2.
What I want to do is to make a SUM on THE QTY column that have the same ITEM_ID=001 and OCCASION=1 AND then deduct the SUM of the QTY with the OCCASION 2 and ITEM_ID=001
TEMPTABLE
ITEM_ID QTY OCCASION
--------------------
001 2 1
002 3 1
001 4 1
003 2 1
001 1 2
For the ITEM_CODE=001 the result should be (2+4)-1=5.
Is it possible to do that with one query?
SELECT ITEM_ID,
SUM(CASE WHEN OCCASION = 1 THEN QTY ELSE 0 END)
- SUM(CASE WHEN OCCASION = 2 THEN QTY ELSE 0 END)
FROM TEMPTABLE
GROUP BY ITEM_ID
Please use the below code. Its working fine in SQL Server 2012.
DECLARE #TEMPTABLE TABLE (ITEM_ID Char(5), QTY int, OCCASION int)
INSERT INTO #TEMPTABLE
(ITEM_ID,QTY,OCCASION)
VALUES
(001,2,1),
(002,3,1),
(001,4,1),
(003,2,1),
(001,1,2)
SELECT ITEM_ID,
SUM(CASE WHEN OCCASION = 1 THEN QTY ELSE 0 END)-
SUM(CASE WHEN OCCASION = 2 THEN QTY ELSE 0 END) AS Total
FROM #TEMPTABLE
GROUP BY ITEM_ID
Output:
ITEM_ID Total
1 5
2 3
3 2
select item_id, sum(qty*(3 - 2*occasion))
from table
group by item_id

SQL SELECT * WHERE value NOT IN list and IN another list

I want to select a SKU that is not in ('DC01','5000'), but is in ('1003','1039','1012') where the SUM is greater than 3. I intend to get back zero records, as the SKU '000000001041106003' is in '1003' with StockOnHand greater than 3, but has a StoreID of 'DC01', however the SKU value of '000000001041106003' is returned. That SKU has a StoreID of 'DC01' and '1003'.
What do I need to do in order to get the desired outcome?
productName SKU StoreId StockOnHand webenabled
.Speedo Yarn 000000001041106001 1003 1 1
.Speedo Yarn 000000001041106002 1003 3 1
.Speedo Yarn 000000001041106003 1003 4 1
.Speedo Yarn 000000001041106003 DC01 0 1
SELECT DISTINCT(SKU)
FROM etlStoreAssortment
WHERE StoreId NOT IN ('DC01','5000')
AND StoreId IN ('1003','1039','1012') GROUP BY SKU HAVING SUM(StockOnHand) > 3
WHERE looks at a single record. There is one record for '000000001041106003' where StoreId NOT IN ('DC01','5000') and StoreId IN ('1003','1039','1012'). What you are looking for though is where at least one record per group has or doesn't have a certain value. Use HAVING for this:
SELECT DISTINCT(SKU)
FROM etlStoreAssortment
GROUP BY SKU
HAVING SUM(StockOnHand) > 3
AND MAX(CASE WHEN StoreId IN ('DC01','5000') THEN 1 ELSE 0 END) = 0
AND MAX(CASE WHEN StoreId IN ('1003','1039','1012') THEN 1 ELSE 0 END) = 1;

Need a query to find count of a column record?

I have a table like this,
ProductId CategoryID bIsPrimary
1 5 1
1 6 0
1 7 0
2 18 1
2 19 1
I need a output like this,
ProductID PrimaryCategoryCount
1 1
2 2
Basically i need to find the the number of primary categories for each product.
SELECT ProductId, COUNT(*)
FROM SomeTable
WHERE bIsPrimary <> 0
GROUP BY ProductId
SELECT
ProductId
,sum(case when bIsPrimary = 1 then 1 else 0 end) as PrimaryCategoryCount
from
Table
group by
ProductId
or
SELECT
ProductId
,count(CategoryId)
from
Table
where bIsPrimiary = 1
group by ProductId
Both will provide you the same result. Pick up one which suits you more or is faster.
SELECT ProductId, COUNT(bIsPrimary)
FROM yourTable
GROUP BY ProductId
This is how I'd do it. WHERE clause isn't necessary here if I'm not mistaken.

Return results where first entry is 1 and all subsequent rows are 0

I m working on weird SQL query
Patient_ID Count order_no
1 1 1
2 1 2
2 0 3
2 0 4
3 1 5
3 0 6
where I need to count the patient as above, for every new patient , the count column is 1.
If repeated , the below entry it should be 0
I m confused how should make that work in SQL
In order to make the first entry 1 and all subsuqent entries 0, I believe you need a ranking with partition by the order number. Please checkout the sqlfiddle below to test results.
http://www.sqlfiddle.com/#!3/4e2e2/17/0
SELECT
patient_id
,CASE WHEN r.rank = 1
THEN 1
ELSE 0
END
, order_number
FROM
(
SELECT
order_number
,patient_id
,ROW_NUMBER() OVER (PARTITION BY patient_id ORDER BY order_number)[rank]
FROM
PatientTable
)r