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