Mysql query to PostgreSQL query - sql

select storeID, itemID, custID, sum(price)
from Sales F
group by storeID, custID, itemID
with cube(storeID, custID);
I am going to use this query in postgreSQL but it doesn't work in postgreSQL directly
how can I convert this query into postgreSQL query?

Your code will work without the with keyword:
select storeID, itemID, custID, sum(price)
from Sales F
group by itemID, cube(storeID, custID);
I prefer grouping sets for expressing groupings:
select storeID, itemID, custID, sum(price)
from Sales F
group by grouping sets ( (storeID, custID, itemID),
(custID, itemID),
(storeID, itemID),
(itemID)
);
If I understand what you want to do, this should be exactly the same.
You could also use cube and then filter:
select storeID, itemID, custID, sum(price)
from Sales F
group by cube(storeID, custID, itemID)
having itemId is not null

Try this:
select storeID, itemID, custID, sum(price)
from Sales F
group by cube (storeID, itemID, custID)
Check this post for more details on CUBE,GROUPING SETS and ROLLUP.

Related

select the latest balance for each product based on store (SQL)

I'm trying to get latest balance for each product based on storeid . But I don know why get result duplicate stock name sasi.
Sql Query
select stockname, balance,updatedat,storename,s1.productid,s1.storeid
from stockmovement s1
inner join (select storeid, productid, max(updatedat) as maxdate
from stockmovement
group by storeid,productid) s2
on s2.storeid = s1.storeid and s2.maxdate = s1.updatedat
This is a greatest-n-per-group problem, and they can be solved efficiently using distinct on () in Postgres:
select distinct on (storeid, productid) *
from stockmovement
order by storeid, productid, updatedat desc
This is typically faster than the equivalent solution using window functions.
Try below query using row_number():
select stockname, balance, bupdatedat, storename,productid,storeid from
(
select stockname, balance, bupdatedat, storename,productid,storeid, row_number() over
(partition by storeid,productid order by bupdatedat date desc) rn
)t where rn=1
select stockname, balance, updatedat, storename,productid,storeid from
(
select stockname, balance, updatedat, storename,productid,storeid, row_number() over
(partition by storeid,productid order by updatedat desc )rn from stockmovement
)t where rn=1

Combine two SQL statements with sum

Two statements need to combine.
select INVOICEAMOUNT, itemid
from MTS_NONPAYMENT
select SUM(AMOUNT) AS SUM, ITEMID
from CUS_GLACCOUNT
Common column itemid. Each time I try and join, it fails. What am I doing wrong?
Fundamentally, you appear to be missing group by. I suspect the following does what you want:
select itemid, sum(invoiceamount) as invoiceamount, sum(sum) as sum
from ((select itemid, sum(INVOICEAMOUNT) as invoiceamount, 0 as sum
from MTS_NONPAYMENT
group by itemid
) union all
(select itemid, 0, SUM(AMOUNT)
from CUS_GLACCOUNT
group by itemid
)
) x
group by itemid;
To get unequal values, use:
having sum(invoiceamount) <> sum(sum)
at the end of the query.

Add row to SQL query results with totals of certain columns

I have a sql query
select * from orderTable
that returns:
I want to have the query return an additional row that has orderId = 'Total' and the sum of GrossAmt, Payments, NetAmt with the remaining fields being empty, like this:
What I've tried:
select isnull(OrderId, 'Total') as OrderId, GrossAmt
from (
select OrderId, SUM(GrossAmt) as GrossAmt
from orderTable
group by OrderId with rollup
) as OT
Which will return the last row with Total and sum of GrossAmt, but when I try to add, say StoreId like:
select isnull(OrderId, 'Total') as OrderId, GrossAmt, StoreId
from (
select OrderId, SUM(GrossAmt) as GrossAmt, StoreId
from orderTable
group by OrderId, StoreId with rollup
) as OT
Then I get double the results with a duplicate for each row only with a null value for StoreId.
I just had the idea to switch the place of OrderId and StoreId in the above query and that has given me my closest results. I have exactly what I want, only there are 2 total rows at the bottom, one with a null StoreId.
You can use UNION to make it a single table:
select * from
(
select cast(OrderId as Varchar) as OrderId, Custname, GrossAmt, Payments, NetAmt, StoreId, StaffName
from orderTable
UNION
(select 'Total' as OrderId, Null as Custname,
Sum(GrossAmt) As GrossAmt,
Sum(Payments) As Payments,
Sum(NetAmt) As NetAmt, Null as StoreId, Null as StaffName
from orderTable)
) a
Notice the cast to have the word Total fit in the OrderId column
SELECT ISNULL(OrderId, 'Total') as OrderId, GrossAmt, NULL AS storeId
FROM (
SELECT OrderId, SUM(GrossAmt) as GrossAmt
FROM orderTable
GROUP BY
OrderId WITH ROLLUP
) AS OT

Using columns as references

everyone.
My question is, if I'm using a column with SUM or COUNT in my SQL, for exemple:
Select ITEM, sum(PRICE), count(ITEM), (<column2>/<column3>)... from TABLE..
Is there a way to use the columns as references?
You need to use a subquery or CTE:
WITH t as (
Select ITEM, sum(PRICE) as price, count(ITEM) as cnt
from TABLE..
)
SELECT item, price, cnt, price / cnt
FROM t;
You can also repeat the expressions. Or, in your particular case, just use AVG():
Select ITEM, SUM(PRICE) as price, count(ITEM) as cnt, AVG(PRICE)
from TABLE..

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