PostgreSQL query to check minimum and maximum data - sql

i have the example database here,
table products
id | name | code | minimum_stock | stock | maximum_stock
1 AAA AAA 50 75 100
2 BBB BBB 70 50 300
3 CCC CCC 100 200 150
4 DDD DDD 40 25 100
5 EEE EEE 70 10 100
in this case i want to show only data who is stock exceed compared by their minimum_stock or maximum_stock(below or above their minimum maximum stock) and also i want to show datain safe stock position (between minimum and maximum stock),
stock value in here is a result from aggregate sum function
if i want only show data exceed minimum stock, the result output must be like this
id | name | code | **minimum_stock** | **stock** | maximum_stock
2 BBB BBB **70** **50** 300
4 DDD DDD **40** **25** 100
5 EEE EEE **70** **10** 100
and if i want only show data exceed maximum stock, the result output must be like this
id | name | code | minimum_stock | **stock** | **maximum_stock**
3 CCC CCC 100 **200** **150**
and the last one the stock between minimum and maximum stock, it must be like this
id | name | code | **minimum_stock** | **stock** | **maximum_stock**
1 AAA AAA **50** **75** **100**
how can I do that?

Try this
Minimum Stock
Select * from table where stock < minimum_stock
maximum stock
Select * from table where stock > maximum_stock
between minimum and maximum stock
Select * from table where stock < maximum_stock and stock > minimum_stock

Related

How to SUM() OVER() by pentaho?

MY data like
| ID | Values |
|:---:|:------:|
| 1 | 200 |
| 2 | 300 |
| 3 | 650 |
| 4 | 120 |
| 5 | 830 |
I want : T-SQL : SUM(Values) OVER(ORDER BY ID) AS Sum
ID
Values
Sum
1
200
200
2
300
500
3
650
1150
4
120
1270
5
830
2100
How should I do by pentaho??
You use the "Group by" step with the Cumulative sum option, and without filling the Group field section so it performs the sum for all the rows:
You'll have to feed the data ordered by ID with a Sort step, in my screenshot I haven't put the Sort step because I have fill up the Data grid with the data ordered, but in your case you might need to make sure the data is ordered first.

Assign new value to every unique number in SQL Server

I am new to SQL Server and trying to do some operations
Sample data:
Amount | BillID
-------+-------
500 | 10009
500 | 1492
350 | 15892
222 | 15596
899 | 20566
350 | 9566
How can I create a new column that holds a serial number according to the Amount column so the output looks like:
Amount | BillID | unique
-------+--------+-------
500 | 10009 | 1
500 | 1492 | 1
350 | 15892 | 2
222 | 15596 | 3
899 | 20566 | 4
350 | 9566 | 2
I would recommend dense_rank():
select t.*, dense_rank() over(order by amount) rn
from mytable t
This assigns a unique, incremental number to each amount. The smallest amount gets ranks 1, and the number are assigned incrementally by increasing amount. This is not exactly the output you showed (where there is no apparent logic to order the ranks), but I think that's the logic you want in essence.

Aggregate columns based on different conditions?

I have a Teradata query that generates:
customer | order | amount | days_ago
123 | 1 | 50 | 2
123 | 1 | 50 | 7
123 | 2 | 10 | 19
123 | 3 | 100 | 35
234 | 4 | 20 | 20
234 | 5 | 10 | 10
With performance in mind, what’s the most efficient way to produce an output per customer where orders is the number of distinct orders a customer had within the last 30 days and total is the sum of the amount of the distinct orders regardless of how many days ago the order was placed?
Desired output:
customer | orders | total
123 | 2 | 160
234 | 2 | 30
Given your rules, maybe it takes two steps - de-duplicate first then aggregate:
SELECT customer,
SUM(CASE WHEN days_ago <=30 THEN 1 ELSE 0 END) AS orders,
SUM(amount) AS total
FROM
(SELECT customer, order, MAX-or-MIN(amount) AS amount, MIN-or-MAX(days_ago) AS days_ago
FROM your_relation
GROUP BY 1, 2) AS DistinctCustOrder
GROUP BY 1;

How can I perform this in a single query

In SQL Server 2008, I have something similar to this:
Accounts:
aaa | 01/01/2010 | 15.00
bbb | 01/01/2010 | 20.00
ccc | 01/01/2010 | 10.00
ddd | 02/01/2010 | 30.00
eee | 04/01/2010 | 25.00
fff | 05/01/2010 | 1.00
Transactions:
aaa | 01/01/2010 | 15.00
aaa | 02/01/2010 | 20.00
aaa | 03/01/2010 | 5.00
bbb | 01/01/2010 | 15.00
bbb | 04/01/2010 | 5.00
ccc | 04/01/2010 | 10.00
ddd | 05/01/2010 | 25.00
I need the results to be something like:
Jan-10 Feb-10 Mar-10 Apr-10 May-10 Accts tot Trans Tot
Jan-10 15 20 5 5 0 45 45
Feb-10 15 0 0 15 0 30 30
Mar-10 0 0 0 0 0 0 0
Apr-10 0 0 0 0 0 25 25
May-10 0 0 0 0 0 0 0
I hope that makes sense... Each cell is the sum of the transactions for accounts created in a certain month. So accounts created in January will have a transaction total each month for the year. The first column is the account date, the row is the transaction date, and the cells are sums anytime an account created in that month has a transaction in the corresponding month.
Right now I do a join on the tables, then loop through and calculate each cell.
The loop is killing my processing time.
I don't think that you'll find a query to return that. Many years ago I was an expert in sqlServer but I've forgot many things about transact-sql, what I did when I had those kind of problems was to create a temporary table with the columns needed based on a query and start inserting the information, using cursors to loop the information. At the end just a "select * from #temp". Hope this idea helps...

SQL how to filter A table with Two ranges in another table

I have a table with Bills, each Bill can have 20 subregister.
Example (Top 5 Per Bill, could be up to 60,000 bills)
(TABLE ONE)
Bill | SubRow |
-----+------------+
1000 | 1 |
1000 | 2 |
1000 | 3 |
1000 | 4 |
1000 | 5 |
1001 | 1 |
1001 | 2 |
1001 | 3 |
1001 | 4 |
1001 | 5 |
In another table, I have the Bill number and a Range of subrows
Example:
(TABLE TWO)
Bill | InitialRange | Final Range|
-----+--------------+------------+
1000 | 1 | 2 |
1000 | 4 | 5 |
1001 | 3 | 5 |
In a query I want to achieve the following:
To show , from table One, all records NOT beetween the ranges in table 2.
That means I should get the following set :
Bill | SubRow |
-----+------------+
1000 | 3 |
1001 | 1 |
1001 | 2 |
What I have so far:
Select Bill,SubRow
from TABLE ONE
LEFT join TABLE TWO ON TABLEONE.Bill= TABLETWO.bill
where Subrow < InitialRange and Subrow > FinalRange
but the second condition in the second row in TABLETWO overrides the first for the 1000 bill.
Any idea on how to achieve this?
note(I the tables appears messed up, I will try to fix it)
Image with Example:
http://postimg.org/image/ymc3z2uzx/
Try this:
SELECT * FROM TABLE_ONE WHERE NOT EXISTS
(SELECT * FROM TABLE_TWO
WHERE TABLE_ONE.Bill = TABLE_TWO.Bill
AND TABLE_ONE.SubRow BETWEEN TABLE_TWO.IinitialRange AND TABLE_TWO.FinalRange)