Having count with case when in a temporary table in snowflake - sql

I'm trying to make a query to return a table based on a having count condition, if the row count is > 2, then it should return me only the max value of a field and make a union with another table. If it's equal to 1, then just pull everything of the table, it would look something a little like this, I don't know the correct syntax for snowflake tho:
WITH TEMP_SHIPMENTS AS (
SELECT
ORDERNUMBER,
POSITIONNUMBER,
ITEMCODE,
ITEMDESCRIPTION,
SHIPMENTNUMBER,
LOAD,
QUANTITY,
SERIALNUMBER,
CUSTOMERNAME,
SHIPTOADDRESS,
MAX(CUSTOMERORDER),
CUSTOMERLINE,
DELIVERYDATE
FROM
T_SHIPMENTS
GROUP BY
ORDERNUMBER,
POSITIONNUMBER,
ITEMCODE,
ITEMDESCRIPTION,
SHIPMENTNUMBER,
LOAD,
QUANTITY,
SERIALNUMBER,
CUSTOMERNAME,
SHIPTOADDRESS,
CUSTOMERORDER,
CUSTOMERLINE,
DELIVERYDATE
)
CASE WHEN HAVING COUNT FROM TEMP_SHIPMENTS.CUSTOMERORDER >2
THEN
SELECT ORDERNUMBER,
POSITIONNUMBER,
ITEMCODE,
ITEMDESCRIPTION,
SHIPMENTNUMBER,
LOAD,
QUANTITY,
SERIALNUMBER,
CUSTOMERNAME,
SHIPTOADDRESS,
CUSTOMERORDER,
CUSTOMERLINE,
MAX(DELIVERYDATE)
FROM TEMP_SHIPMENTS;
Any ideas on how I could achieve it?
SELECT
ORDERNUMBER,
POSITIONNUMBER,
ITEMCODE,
ITEMDESCRIPTION,
SHIPMENTNUMBER,
LOAD,
QUANTITY,
SERIALNUMBER,
CUSTOMERNAME,
SHIPTOADDRESS,
CUSTOMERORDER,
CUSTOMERLINE,
DELIVERYDATE
FROM
T_SHIPMENTS
WHERE SerialNumber = '012501003449' ;
Result table from query
I left the result in here, and as you can see I have the same serialNumber with two records, which is okay but I only need one. And that would be the one that has either the greatest datetime or the greatest customerorder number. I tried by querying with the max value but achieved nothing on either of these fields, I still get two records instead of just one with the maximum value

If you would like to return the row of the MAX(CUSTOMERORDER), I would try:
WITH TEMP_SHIPMENTS AS (
SELECT ROW_NUMBER() over (PARTITION BY SERIALNUMBER ORDER BY CUSTOMERORDER desc) row_num,
ORDERNUMBER,
POSITIONNUMBER,
ITEMCODE,
ITEMDESCRIPTION,
SHIPMENTNUMBER,
LOAD,
QUANTITY,
SERIALNUMBER,
CUSTOMERNAME,
SHIPTOADDRESS,
CUSTOMERORDER,
CUSTOMERLINE,
DELIVERYDATE
FROM
T_SHIPMENTS
)
SELECT *
FROM TEMP_SHIPMENTS
WHERE row_num = 1
It's unclear by your question if this should be the max ordernumber over the entire table or max ordernumber for a group - based on the image you attached it sounds like you want the max ordernumber for each serialnumber, so that is what I partitioned over. However, you can make that partition be itemdescription or customername if you'd like the max ordernumber of an item or customer, respectively.

I'm afraid you can't really do conditional unions in pure SQL in any database, nor use HAVING clause for anything else than grouping results refinement.

Related

SQL-select two values that are the same in different rows but still be able to see a third value

i have three columns orderdate, customerid and productid. i only want to see the rows where orderdate and customerid is repeated. so when the customer orders something on the same day. but i also want to see the product id.
SELECT orderdate, customerid, productid
FROM sales_orders_sheet
GROUP BY orderdate, customerid
HAVING COUNT(*)>1
when I use this sql statement I get;
Field of aggregated query neither grouped nor aggregated: line 1, column 31
You can do:
select *
from (
select t.*, count(1) over(partition by orderdate, customerid) as cnt
from sales_orders_sheet t
) x
where cnt > 1

Get the date for each duplicated row in SQL Server

I've made a query to get how many products are sold more than one time and it worked.
Now I want to show the transaction date for each of these duplicated sales, but when I insert the date on the select it brings me a lot less rows: something is going wrong. The query without the date returns 9855 rows and with the date just 36 rows.
Here is the query I'm doing:
SELECT TransactionDate,
ProductName,
QtyOfSales = COUNT(*)
FROM product_sales
WHERE ProductID = 1 -- Product Sold ID
AND ProductName IS NOT NULL
GROUP BY ProductName,
TransactionDate
HAVING COUNT(*) > 1
Perhaps a subquery? Can you help in that regard?
You can use the corresponding COUNT window function, that will find the amount of transactions by partitioning on the "ProductName" as required:
WITH cte AS(
SELECT TransactionDate,
ProductName,
COUNT(*) OVER(PARTITION BY ProductName) AS QtyOfSales
FROM product_sales
WHERE ProductID = 1 -- Product Sold ID
AND ProductName IS NOT NULL
)
SELECT DISTINCT TransactionDate,
ProductName
FROM cte
WHERE QtyOfSales > 1

SQL divide the column values to equal groups with ntile

I need to write sql query that divide the products to 3 equal groups by their price, (The cheapest products will be in the first group). For each group I have to present the price ranges it includes and the average units in stock.
I try to use ntile but I got stuck:
SELECT UnitPrice, NTILE(3) OVER (
ORDER BY UnitPrice ASC
) AS productGroup, UnitsInStock
FROM Products
You need to put a query on top of this one. Something like this:-
select productGroup, min(UnitPrice), max(UnitPrice), avg(UnitPrice)
from (
SELECT UnitPrice, NTILE(3) OVER (ORDER BY UnitPrice ASC) AS productGroup
, UnitsInStock
FROM Products
) t1
group by productGroup

Group By First Row

SELECT OrderNumber, FIRST(ShippingName) as ShippingName FROM Orders
GROUP BY OrderNumber
This gives an error, how would I do this?
The FIRST function is not supported in SQL Server.
Maybe you want
SELECT OrderNumber, MIN(ShippingName) as ShippingName
FROM Orders
GROUP BY OrderNumber
But, probably not. Instead I suspect you mean... for each OrderNumber, of all the rows with that OrderNumber, select the ShippingName of the first row according to some ordering.
SELECT OrderNumber,
(
SELECT TOP 1 ShippingName
FROM Orders AS OrdersInner
WHERE OrdersInner.OrderNumber = Orders.OrderNumber
ORDER BY OrdersInner.OrderDate, OrdersInner.OrderId
) as ShippingName
FROM Orders
GROUP BY OrderNumber
But I'm making some assumptions about both your requirements and your database structure.
You maybe mean :
SELECT TOP 1 OrderNumber, ShippingName
FROM Orders
ORDER BY OrderNumber DESC

Dedupe records without DELETE

I need to bring back only one of the records from a duplicated row in SQL Server
I have data like this
-------------------------------------------
CustomerID, OrderID, ProductID, Title
-------------------------------------------
1,1001,131,orange
1,1002,131,orange
-------------------------------------------
These rows are shown as 2 items that have been ordered by the same person, really they are just two as the quantity chosen in the basket and 2 records.
My question is how can i retrieve only one of these rows?
Thanks
Maybe something like this:
First some test data:
DECLARE #tbl TABLE(CustomerID INT,OrderID INT,ProductID INT,Title VARCHAR(100))
INSERT INTO #tbl
VALUES
(1,1001,131,'orange'),
(1,1002,131,'orange')
Then the query
;WITH CTE AS
(
SELECT
ROW_NUMBER() OVER(PARTITION BY tbl.CustomerID,tbl.ProductID,tbl.Title
ORDER BY tbl.OrderID) AS RowNbr,
tbl.CustomerID,
tbl.OrderID,
tbl.ProductID,
tbl.Title
FROM
#tbl AS tbl
)
SELECT
*
FROM
CTE
WHERE
CTE.RowNbr=1
This way you can get, not only one of both rows, but also the quantity ordered
SELECT
CustomerID, ProductID, Title, max(OrderID) as orderID, COUNT(*) as quantity
FROM
TableName
GROUP BY
CustomerID,
ProductID,
Title
Using Max will get you the most recent order
SELECT CustomerID, MAX(OrderId), ProductID, Title
FROM table
GROUP BY CustomerID, ProductID, Title
OR
Using Min will get you the first order
SELECT CustomerID, MIN(OrderId), ProductID, Title
FROM table
GROUP BY CustomerID, ProductID, Title
Provided that it's really what you want you can get the first order of each order with the same customer, product and title using a grouping and the MIN function (MAX would give you the last order):
SELECT CustomerID, MIN(OrderID) AS OrderID, ProductID, Title
FROM MyTable
GROUP BY CustomerID, ProductID, Title
If you want the number of duplicate orders (that would be the ordered quantity judging by your question) you can add a count:
SELECT CustomerID, MIN(OrderID) AS OrderID, ProductID, Title,
COUNT(*) AS Quantity
FROM MyTable
GROUP BY CustomerID, ProductID, Title