Kindly advice on how to group the data in SQL - sql

Example table
Cust_no | Item_no | Discount_Amt |Discount_%|
A123 | ITEM123 | 0.1 | |
AB321 | ITEM123 | 50 | |
A123 | ITEM123 | | 3 |
CD343 | ITEM345 | | 2 |
and the result I want:
Cust_no | Item_no | Discount Amt| Discount_%|
A123 | ITEM123 | 0.1 | 3 |
AB321 | ITEM123 | 50 | 0 |
CD343 | ITEM345 | | 2 |
How can I get that result in SQL?

Try this :
SELECT Cust_no,Item_no,SUM(Discount_Amt),SUM(Discount_%)
FROM TableName
GROUP BY Cust_no,Item_no

I think you are looking something similar to this
SELECT Cust_no,Item_no, MAX(Discount_Amt),MAX(Discount_%)
FROM Table
GROUP BY Cust_no, Item_no

Related

mySQL : Populate a column with the result of a query

I have a table ORDERS with a column named cache_total_price, spent by each client.
+----+-----------+------------+-----------+------------------+
| id | client_id | date | reference | cache_total_price|
+----+-----------+------------+-----------+------------------+
| 1 | 20 | 2019-01-01 | 004214 | 0 |
| 2 | 3 | 2019-01-03 | 007120 | 0 |
| 3 | 11 | 2019-01-04 | 002957 | 0 |
| 4 | 6 | 2019-01-07 | 003425 | 0 |
I have another table ORDERS_REFS where there is the price total spent for each orders id
+-----+-------------+------------+----------+---------------+------------+
| id | order_id | name | quantity | unit_price | total_price|
+-----+-------------+------------+----------+---------------+------------+
| 1 | 1 | Produit 19 | 3 | 49.57 | 148.71 |
| 2 | 1 | Produit 92 | 4 | 81.24 | 324.96 |
| 3 | 1 | Produit 68 | 2 | 17.48 | 34.96 |
| 4 | 2 | Produit 53 | 4 | 83.69 | 334.76 |
| 5 | 2 | Produit 78 | 6 | 5.99 | 35.94 |
I want to had to column cache_total_price the result of my query :
select sum(total_price) from orders_refs group by order_id;
result :
+--------------------+
| sum(total_price) |
+--------------------+
| 508.6299819946289 |
| 370.700008392334 |
| 132.3699951171875 |
| 2090.1800079345703 |
I've tried some queries with Insert into select or update set, but didn't worked :(
If you're wanting to update all the orders at once, in MySQL a subquery like this should do the trick. You could always add a WHERE clause to do one at a time.
UPDATE ORDERS
SET cache_total_price = (
SELECT sum(total_price) from ORDERS_REF where order_id = ORDERS.id
)
update t
set t.cache_total_price=x.sum_total_price
from ORDERS as t
join
(
select order_id,sum(total_price)as sum_total_price
from orders_refs group by order_id
)x on t.id=x.order_id
In SQL Server you can try this one.

Postgres multi row to string and calculate

I have these table :
tblproduk :
| skuid | namabarang |
|--------|-----------------|
| 123456 | INDOMIE GORENG |
| 234567 | COKLAT BENGBENG |
| 345678 | BISKUIT |
tblproduk_satuan:
| id | skuid | kodebarang | satuan | konversi | price |
|----|--------|------------|--------|----------|--------|
| 1 | 123456 | ABC1 | PCS | 1 | 6000 |
| 2 | 123456 | ABC2 | DUS | 20 | 100000 |
| 3 | 234567 | BCD | PCS | 1 | 3000 |
| 4 | 345678 | CDE1 | BKS | 1 | 4500 |
| 5 | 345678 | CDE2 | LSN | 12 | 50000 |
| 6 | 345678 | CDE3 | DUS | 48 | 190000 |
tblproduk_stock:
| id | skuid | awal | masuk | keluar |
|----|--------|------|-------|--------|
| 1 | 123456 | 10 | 50 | 30 |
| 2 | 234567 | 0 | 100 | 20 |
| 3 | 345678 | 20 | 400 | 21 |
Here is the sqlfiddle of my table.
What is the the most efficient way to convert multi row to string from tblproduct_satuan, make calculation and display it like this :
| skuid | namabarang | stock | satuan |Remarks | Amount
|--------|-----------------|-------|--------|-------------------------------
| 123456 | INDOMIE GORENG | 30 | PCS | 1 DUS 10 PCS | 160.000
| 234567 | COKLAT BENGBENG | 80 | PCS | 80 PCS | 240.000
| 345678 | BISKUIT | 399 | BKS | 8 DUS 1 LSN 3 BKS | 1.583.500
Hope to get help from the expert.
Thank you
If I understood correctly, Here is the query for your requirement:
WITH CTE AS (
select
t1.skuid,
t1.namabarang,
t3.masuk+t3.awal-t3.keluar "stock",
t2.satuan,
t2.konversi,
floor(mod((t3.masuk+t3.awal-t3.keluar),coalesce(lag(t2.konversi) over (partition by t1.skuid order by t2.konversi desc ),(t3.masuk+t3.awal-t3.keluar)+1))/t2.konversi) "count_",
t2.price,
row_number() over (partition by t1.skuid order by t2.konversi) "rn"
from
tblproduct t1
inner join tblproduct_satuan t2 on t1.skuid=t2.skuid
inner join tblproduct_onhand t3 on t3.skuid=t1.skuid
)
select
skuid,
namabarang,
stock,
min(satuan) filter (where rn=1) "satuan",
string_agg(concat(count_,' ',satuan), ' ' order by konversi desc) "Remarks",
sum(price*count_) "Amount"
from cte
group by 1,2,3
In With block I have calculated all the required values and then aggregated for final output.
DEMO

How to group and order rows with different date values in SQL

I have a result like this:
+---------------------------+-----------+------------+
| Date | InvoiceID | Amount |
+---------------------------+-----------+------------+
| 2020-06-09 12:36:37.433 | AF-1 | 189,876996 |
| 2020-06-09 12:36:37.483 | AF-1 | 59,4 |
| 2020-06-09 12:36:37.490 | AF-1 | 15,8544 |
| 2020-06-09 12:37:42.790 | AF-2 | 20,2 |
| 2020-06-09 12:39:29.453 | AF-4 | 70,6596 |
| 2020-06-09 12:43:30.553 | SF-1 | 47,1064 |
| 2020-06-09 12:43:30.577 | SF-1 | 12,96 |
| 2020-06-09 12:43:30.583 | SF-1 | 17,3664 |
| 2020-06-09 12:44:51.963 | SF-3 | 34,3905 |
| 2020-06-09 12:49:34.147 | TM-1 | 500 |
| 2020-06-09 12:50:26.040 | TM-2 | 150 |
| 2020-06-09 12:50:26.063 | TM-2 | 600 |
| 2020-06-09 12:51:29.817 | GH-1 | 500 |
| 2020-06-09 12:51:29.823 | GH-1 | 313,68 |
+---------------------------+-----------+------------+
Query is pretty simple:
Select Date, InvoiceID, Amount from TableName order by Date
I need to group them, get sum of amount and order by date. Notice that date values are not the same. I can't group results because of this. Important thing is i need to order by Date column. This is the result i want:
+-----------+-------------+
| InvoiceID | Amount |
+-----------+-------------+
| AF-1 | 265,131396 |
| AF-2 | 20,2 |
| AF-4 | 70,6596 |
| SF-1 | 77,4328 |
| SF-3 | 34,3905 |
| TM-1 | 500 |
| TM-2 | 750 |
| GH-1 | 813,68 |
+-----------+-------------+
I'm trying this code but sql gave me an error that i need to use Date column in group by clause.
SELECT InvoiceID, sum(Amount) as Amount from TableName group by InvoiceID order by Date
I'm very new to SQL, can anyone suggest how can i solve that problem please?
You want aggregation, but you need an aggregation function for the ordering as well:
SELECT InvoiceID, sum(Amount) as Amount
FROM TableName
GROUP BY InvoiceID
ORDER BY MIN(Date);

Finding MAX date aggregated by order - Oracle SQL

I have a data orders that looks like this:
| Order | Step | Step Complete Date |
|:-----:|:----:|:------------------:|
| A | 1 | 11/1/2019 |
| | 2 | 11/1/2019 |
| | 3 | 11/1/2019 |
| | 4 | 11/3/2019 |
| | 5 | 11/3/2019 |
| | 6 | 11/5/2019 |
| | 7 | 11/5/2019 |
| B | 1 | 12/1/2019 |
| | 2 | 12/2/2019 |
| | 3 | |
| C | 1 | 10/21/2019 |
| | 2 | 10/23/2019 |
| | 3 | 10/25/2019 |
| | 4 | 10/25/2019 |
| | 5 | 10/25/2019 |
| | 6 | |
| | 7 | 10/27/2019 |
| | 8 | 10/28/2019 |
| | 9 | 10/29/2019 |
| | 10 | 10/30/2019 |
| D | 1 | 10/30/2019 |
| | 2 | 11/1/2019 |
| | 3 | 11/1/2019 |
| | 4 | 11/2/2019 |
| | 5 | 11/2/2019 |
What I need to accomplish is the following:
For each order, assign the 'Order_Completion_Date' field as the most recent 'Step_Complete_Date'. If ANY 'Step_Complete_Date' is NULL, then the value for 'Order_Completion_Date' should be NULL.
I set up a SQL FIDDLE with this data and my attempt, below:
SELECT
OrderNum,
MAX(Step_Complete_Date)
FROM
OrderNums
WHERE
Step_Complete_Date IS NOT NULL
GROUP BY
OrderNum
This is yielding:
ORDERNUM MAX(STEP_COMPLETE_DATE)
D 11/2/2019
A 11/5/2019
B 12/2/2019
C 10/30/2019
How can I achieve:
| OrderNum | Order_Completed_Date |
|:--------:|:--------------------:|
| A | 11/5/2019 |
| B | NULL |
| C | NULL |
| D | 11/2/2019 |
Aggregate function with KEEP can handle this
select ordernum,
max(step_complete_date)
keep (DENSE_RANK FIRST ORDER BY step_complete_date desc nulls first) res
FROM
OrderNums
GROUP BY
OrderNum
You can use a CASE expression to first count if there are any NULL values and if not then find the maximum value:
Query 1:
SELECT OrderNum,
CASE
WHEN COUNT( CASE WHEN Step_Complete_Date IS NULL THEN 1 END ) > 0
THEN NULL
ELSE MAX(Step_Complete_Date)
END AS Order_Completion_Date
FROM OrderNums
GROUP BY OrderNum
Results:
| ORDERNUM | ORDER_COMPLETION_DATE |
|----------|-----------------------|
| D | 11/2/2019 |
| A | 11/5/2019 |
| B | (null) |
| C | (null) |
First, you are representing dates as varchars in mm/dd/yyyy format (at least in fiddle). With max function it can produce incorrect result, try for example order with dates '11/10/2019' and '11/2/2019'.
Second, the most simple solution is IMHO to use fallback date for nulls and get null back when fallback date wins:
SELECT
OrderNum,
NULLIF(MAX(NVL(Step_Complete_Date,'~')),'~')
FROM
OrderNums
GROUP BY
OrderNum
(Example is still for varchars since tilde is greater than any digit. For dates, you could use 9999-12-31, for instance.)

Having Groups based on distinct count of another column

I have a table as follow :
+-------------+-----------+------+
| GroupNumber | TeamName | Goal |
+-------------+-----------+------+
| 1 | Sales | ABC |
| 1 | Sales | ABC |
| 1 | Sales | ABC |
| 1 | Design | XYZ |
| 2 | Design | XYZ |
| 2 | Sales | XYZ |
| 2 | technical | XYZ |
| 2 | Support | XYZ |
| 3 | Sales | XYZ |
| 3 | Sales | XYZ |
| 3 | Sales | XYZ |
+-------------+-----------+------+
I want to output only the groups that have unique teams greater than 3.
Only group 2 has this condition so the output is :
Expected Output:
+-------------+-----------+------+
| GroupNumber | TeamName | Goal |
+-------------+-----------+------+
| 2 | Design | XYZ |
| 2 | Sales | XYZ |
| 2 | technical | XYZ |
| 2 | Support | XYZ |
+-------------+-----------+------+
not sure how to utilize this in subquery
SELECT count(Distinct(TeamName))
FROM mytable
group by [GroupNumber]
HAVING COUNT(Distinct[TeamName])>3
Simply put it in a Subquery:
select *
from mytable
where [GroupNumber] in
(
SELECT [GroupNumber]
FROM mytable
group by [GroupNumber]
HAVING COUNT(Distinct[TeamName])>3
)
Please try
SELECT *
FROM mytable where GroupNumber in (select GroupNumber
FROM mytable group by TeamName
HAVING COUNT(TeamName)>3)