How to create this View in SQL - sql

I would like to create a view that returns information about articles whose condition on individual warehouses fell below 20% compared to the previous day.
My table structure is as follows:
I have no idea how to create such a view. Any help or suggestion is welcome. Thanks in advance!

Your question is a bit vague. For instance, what if data for a day is missing? You also mention "warehouses", but there is no such field in the data. Similarly, "condition" is a bit hard to follow. That said, let me assume that you mean "previous day in the data for individual articles and you are interested in quantities that fall by 20%".
select t.*
from (select t.*,
lag(t.quantity) over (partition by articlename order by dateadd) as prev_quantity
from t
) t
where t.quantity < t.prev_quantity * (1 - 0.2);

Related

How to get last value from a table category wise?

I have a problem with retrieving the last value of every category from my table which should not be sorted. For example i want the daily inventory value of nov-1 last appearance in the table without sorting the column daily inventory i.e "471". Is there a way to achieve this?
similarly i need to get the value of the next week's last daily inventory value and i should be able to do this for multiple items in the table too.
p.s: nov-1 represents nov-1 st week
Question from comments of initial post: will I be able to achieve what I need if I introduce a column id? If so, how can I do it?
Here's a way to do it (no guarantee that it's the most efficient way to do it)...
;WITH SetID AS
(
SELECT ROW_NUMBER() OVER(PARTITION BY Week ORDER BY Week) AS rowid, * FROM <TableName>
),
MaxRow AS
(
SELECT LastRecord = MAX(rowid), Week
FROM SetID
GROUP BY Week
)
SELECT a.*
FROM SetID a
INNER JOIN MaxRow b
ON a.rowid = b.LastRecord
AND b.Week = a.Week
ORDER BY a.Week
I feel like there's more to the table though, and this is also untested on large amounts of data. I'd be afraid that a different RowID could be potentially assigned upon each run. (I haven't used ROW_NUMBER() enough to know if this would throw unexpected data.)
I suppose this example is to enforce the idea that, if you had a dedicated rowID on the table, it's possible. Also, I believe #Larnu's comment to you on your original post - introducing an ID column that retains current order, but reinserting all your data - is a concern too.
Here's a SQLFiddle example here.

Looking for identical sequences over all users

I want to get the identical pathes (with counts) of all users
Hey everybody,
Want to keep the question short and hopefully it‘s clear what I want.
I have a table in BigQuery. There I have the following columns
- UserID
- Timestamp
- Domain
- some other columns (but I guess they are unimportant)
I have totally no idea how to fix this!
So I want to look for the same paths over all users and count how many users have the same sequence of domains.
Problem: We are talking about 129 000 users and around 5TB of data. I guess I have to limit the amount of path length or something else.
I‘m familiar with SQL but I need some help/input to keep the costs low. Every query costs money and my thought was to ask the community before I spend thousands of Dollars.
Thanks for any input!
EDIT:
I tried the following to rank the visits of domains:
SELECT
guid,
domain AS channel,
timestamp,
RANK() OVER (PARTITION BY guid ORDER BY timestamp ASC ) AS rank
FROM
data.all
My problem is now: How can I match identical pathes afters merge each "step" in this customer journey?
This may help or at least help you get started:
select domains, count(*)
from (select userid, string_agg(domain order by timestamp, ',') as domains
from t
group by userid
) u
group by domains;
I would prefer to use arrays to store the path itself, but BigQuery does not (yet) support arrays as GROUP BY keys.

Any suggestions to speed up slow geography query?

We have a table of Customers, with each one's location as a Geography column, and a table of Branch Offices also with each one's location as a Geography column (we populate the Geography columns from latitude and longitude columns)
We need to run a query (view) that's intended to show the closest branch office to each customer, based on Geography columns, and it runs fine with a couple of thousand customers. We just received a big job that needs to run with 700,000 customers and it takes hours to run. Can anyone suggest any ways to speed up this SQL?
WITH CLOSEST AS (
SELECT *, ROW_NUMBER()
OVER (
PARTITION BY CustNum
ORDER BY Miles
) AS RowNo
FROM
(
SELECT
CustNum,
BranchNum,
CONVERT(DECIMAL(10, 6), (BranchLoc.STDistance(CustLoc)) / 1609.344) AS Miles
FROM
Branch_Locations
CROSS JOIN
Cust_Locations
) AS T
)
SELECT TOP 100 PERCENT CustNum, BranchNum, Miles, RowNo FROM CLOSEST WHERE RowNo = 1 ORDER BY CustNum, MILES
Could there be a way to put the distance comparison into the JOIN? Nothing comes to mind so far...
Thanks for any suggestions!
So, what you're doing here is calculating the distance from each point to each other point, then ranking. SQL Server Spatial is actually set up in such a way that this is entirely unnecessary.
The first thing you want to do is make a spatial index on each table; documentation on how to do this can be found here. Don't worry too much about the specific paramters here, while you can definitely improve performance by adjusting them, having a spatial index at all will drastically improve performance.
The second thing you want to do is to make sure the spatial index is being used; documentation on how to make sure this happens can be found here. Make sure that you filter out any null spatial information!
So, what this has told as so far is a way to take a point and find the closest point in another long list of tables; but this is SQL Server, we want to to this set based!
My recommendation is to use a little a priori knowledge and write a query using that.
WITH CLOSEST AS (
SELECT
C.CustNum,
B.BranchNum,
ROW_NUMBER() OVER (PARTITION BY C.CustNum ORDER BY B.BranchLoc.STDistance(C.CustLoc)/1609.344 ASC) AS Miles
FROM
Branch_Locations B
INNER JOIN
Cust_Locations C
ON
B.BranchLoc.STDistance(C.CustLoc)/1609.344 < 100 --100 miles as a maximum search distance is a reasonable number to me
WHERE
B.BranchLoc IS NOT NULL
AND C.CustLoc IS NOT NULL
) AS T
SELECT
CustNum,
BranchNum,
Miles,
RowNo
FROM
CLOSEST
WHERE
RowNo = 1
ORDER BY
CustNum,
MILES
There are other techniques that you can use, such as my response here, however at the end of the day the most important takeaway is to create spatial indexes and make sure they are used.

Total Count of each subtype and assign to every record again

I am novice to SQL. I am learning count(). So here is what I am trying to do. There is a table in which Products and Product Types are listed. I want an output which will have a separate column which gives total count of each product_type and assigns it to every record. Can anyone help me to write this query? I searched the forums, but couldn't find similar requirement. Please find attached image for Source table and target table example.
Thank you,
DP
Case for SQL Query
Use windowed COUNT:
SELECT Product,
Product_Type,
COUNT(*) OVER(PARTITION BY Product_Type) AS "Count"
FROM table

SQL Server - Variation auto increment based on primary key

my scenario is this:
Say within an engineering environment, works for a job are quoted at £5,000. However after this a variation is made an additional cost is required for £500.
now within SQL Server I have a table, lets call it Costing. This is associated to the Customer table (1 to many) 1 Customer could have many costs...
Now my question is this... is it possible to auto increment a variation number within the CostingTable, baring in mind that the CostingID is already auto incrementing or is there a different approach I can take?
Example data:
ive already done all the costing calculations etc so this is no issue, its just if it is possible to automatically add one to the VariationNumber based upon the CustomerID... thanks guys
If you want just to display it then use this:
SELECT *,
ROW_NUMBER() OVER(PARTITION BY CustomerId ORDER BY CostingId) AS Variation
FROM Costing
But if you want to store it:
;WITH MyCTE AS
(
SELECT *,
ROW_NUMBER() OVER(PARTITION BY CustomerId ORDER BY CostingId) AS NewVariation
FROM Costing
)
UPDATE MyCTE
SET Variation = NewVariation