SQL Query to show all columns - sql

I have the following table and a SQL query to determine if any items in a table have a buy price higher than a sell price.
Query:
SELECT id, name
FROM orders
GROUP BY id, name
HAVING MAX(CASE WHEN buy = 'false' THEN price END) > MIN(CASE WHEN buy = 'true' THEN price END)
The problem is that this only returns two rows:
The result I am looking for should show all the items that have a buy price higher than a sell price with all the columns. Reading up on GROUP BY I see that it only returns distinct values. Do I have to use joins to achieve the end result?
|id |buy |date |price |name
--------------------------------------------------
3 false 2017-01-04 19:23:12.000 7 bread
3 false 2017-01-04 19:23:12.000 4 bread
2 false 2017-01-04 19:23:12.000 7 grapes
Using this query the result is the table below the rows highlighted in red shouldn't be there.
SELECT *
FROM orders
WHERE id IN (SELECT id
FROM orders
GROUP BY id, name
HAVING MAX(CASE WHEN buy = 'false' THEN price END) > MIN(CASE WHEN buy = 'true' THEN price END))

Use your existing query as a subquery:
SELECT * from orders where id in
(
SELECT id
FROM orders
GROUP BY id, name
HAVING MAX(CASE WHEN buy = 'false' THEN price END) > MIN(CASE WHEN buy = 'true' THEN price END)
)

Related

T-SQL - Pivot out Distinct N rows for each group

I have a table similar to the one below with customers, products, and purchase date. I am trying to get a list of customers and their 3 most recently purchased DISTINCT products. I want to use purchase date as a means of ordering the results, but I don't want to see duplicate product IDs.
Customer
Product
PurchaseDate
1
a
2020-12-5
2
b
2020-12-5
1
a
2020-12-4
2
a
2020-12-3
1
b
2020-12-2
2
b
2020-12-1
1
c
2020-11-30
1
d
2020-11-29
2
b
2020-11-28
Ideally I would see results like this
Customer
Product1
Product2
Product3
1
a
b
c
2
b
a
I have tried partition by statements and order by statements, but everything wants me to include date in the final output. Is there a way to do this?
Most recent distinct products is tricky. This requires one level of aggregation per customer and product and then another for pivoting:
select customer,
max(case when seqnum = 1 then product end) as product_1,
max(case when seqnum = 2 then product end) as product_2,
max(case when seqnum = 3 then product end) as product_3
from (select customer, product, max(purchasedate) as max_purchasedate,
row_number() over (partition by customer order by max(purchasedate) desc) as seqnum
from t
group by customer, product
) cp
group by customer;

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 find total count of each type in a column

I'm learning SQL and am stumped on what should be a simple query. I have a table with the following pattern:
Id | Type
------------
1 | Red
2 | Blue
3 | Blue
4 | Red
..
I would like to write a query to return a table that counts the total number of instances of each type and returns a table with the following pattern, for example, if 'Blue' occurs in 12 rows, and 'Red' occurs in 16 rows in the table above, the result would be:
Blue | Red
-----------
12 | 16
You could do it this way:
SELECT Type, COUNT(*) FROM TABLE GROUP BY Type
If you'd like to see the Types in separate columns, you could do this:
SELECT SUM(CASE WHEN Type = 'Blue' THEN 1 ELSE 0 END) AS Blue, SUM(CASE WHEN Type = 'Red' THEN 1 ELSE 0 END) AS Red FROM TABLE
I suggest using count over partition by. Here's a code I wrote to help my company check for duplicate Technician EmployeeID's and Pincodes, including count and YES/NO columns to allow filtering in excel so they can see what corrections need to be made:
select
t.TechnicianId, t.TechnicianName, t.Pincode, t.EmployeeID
, [Pincode Count] = count(t.Pincode) over (partition by t.Pincode)
, [Duplicate Pincode?] = case count(t.Pincode) over (partition by t.Pincode) when 1 then 'NO' else 'YES' end
, [EmployeeID Count] = count(t.EmployeeID) over (partition by t.EmployeeID)
, [Duplicate EmployeeID?] = case count(t.EmployeeID) over (partition by t.EmployeeID) when 1 then 'NO' else 'YES' end
from Technicians t
group by t.TechnicianId, t.TechnicianName, t.Pincode, t.EmployeeID
order by 4

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;

SQL- Calculating SUM/COUNT with rows of table

I have a PriceComparison table with (StoreNumber, ItemNumber, Price) that keeps pricing data for head-to-head comparison shopping. The goal is a recordset with the following things for all stores:
StoreNumber
COUNT of head-to-head wins for that store
COUNT of head-to-head losses for that store
COUNT of head-to-head ties for that store
SUM of all item pricing for that store
SUM of all head-to-head competitor pricing for items above for that store
Example:
StoreNumber ItemNumber Price
----------- ---------- -----
101 1 1.39
102 1 1.89
101 2 3.49
103 2 2.99
101 3 9.99
104 3 9.99
I'm thinking I can calculate these SUMs and COUNTs if I can get a temporary column added for CompetitorPrice. That way, the item has both prices listed, and it becomes easy.
How can I get this information in the correct configuration? I tried an INNER JOIN to the same table, but that gets tricky.
Thanks!
UPDATE: This is for MS SQL Server.
UPDATE: There will only be two prices per item, no more than 2 stores.
SELECT
a.storenumber,
SUM(CASE WHEN a.price < b.price THEN 1 ELSE 0 END) AS wins,
SUM(CASE WHEN a.price > b.price THEN 1 ELSE 0 END) AS losses,
SUM(CASE WHEN a.price = b.price THEN 1 ELSE 0 END) AS ties,
SUM(a.price) AS store_price_sum,
SUM(b.price) AS competitor_price_sum
FROM
pricecomparison a
INNER JOIN
pricecomparison b ON
a.itemnumber = b.itemnumber AND
a.storenumber <> b.storenumber
GROUP BY
a.storenumber