SQL - Redshift Lag Function getting duplicates - sql

I have a table below
ID Type Sub_ID Date CNT
A P A1 4/1/2020 5
A P A2 4/5/2020 NULL
A P A3 4/8/2020 NULL
What I want to get is
ID Type Sub_ID Date CNT LAG
A P A1 4/1/2020 5 NULL
A P A2 4/5/2020 NULL 5
A P A3 4/8/2020 NULL NULL
I have below queries but it's giving me duplicates like
ID Type Sub_ID Date CNT LAG
A P A1 4/1/2020 5 NULL
A P A1 4/1/2020 5 5 (duplicate)
A P A2 4/5/2020 NULL 5
A P A2 4/5/2020 NULL NULL (duplicate)
A P A3 4/8/2020 NULL NULL
select *, lag(cnt,1) over (partition by id, type order by date)
from mytable
Anything wrong?

Ok...I have duplicate data in my table..Need to dedup first and then do the lag on top of the cleaned table

Related

How can I separate a sum of widgets ordered by a vendor when I am using the select sum in a subquery? I tried group by and it still only gives total

I am trying to separate the sums in a sub query with a group by and I have three tables. I have included my current query below and tables I am using.
SELECT DISTINCT
st.stocknumber,
st.locationnumber,
P3.vendornumber,
(
SELECT SUM
( P2.orderquantity )
FROM
PH2 P2
LEFT OUTER JOIN PH1 P1 ON P1.ponumber = P2.ponumber
WHERE
p1.dateordered BETWEEN '10/13/2021'
AND '10/13/2022'
AND p2.location = 'A1'
AND p2.stocknumber = ST.stocknumber
Group BY p2.vendornumber
) As PHOrderQty
FROM
stok ST
left outer join PH2 P3 on (ST.stocknumber = P3.stocknumber)
WHERE
ST.location = 'A1'
AND ST.stocknumber IN (
'22-2552'
'JW00',
'JS20FT',
'JW090'
)
ORDER BY
stocknumber
Data looks like this
Stock Table - ST
stocknumber
location
22-2552
A1
PO Head Table - PH1
n/a
location
dateordered
ponumber
NULL
A1
10/14/2022
1
NULL
A1
10/14/2022
2
NULL
A1
10/14/2022
3
NULL
A1
10/14/2022
4
PO Details Table - PH2
stocknumber
quantityordered
vendornumber
ponumber
22-2552
3
15
1
22-2552
2
20
2
22-2552
1
15
3
22-2552
4
20
4
I keep getting back
stocknumber
location
vendornumber
PHorderQty
22-2552
A1
15
10
22-2552
A1
20
10
What I should be getting back is
stocknumber
location
vendornumber
PHorderQty
22-2552
A1
15
4
22-2552
A1
20
6
Try with the following one:
SELECT ST.stocknumber,
PH1.location,
PH2.vendornumber,
SUM(PH2.quantityordered) AS phOrderQty
FROM stock ST
INNER JOIN head PH1
ON PH1.location = PH1.location
INNER JOIN details PH2
ON ST.stocknumber = PH2.stocknumber
AND PH1.ponumber = PH2.ponumber
WHERE ST.stocknumber IN ('22-2552', 'JW00', 'JS20FT', 'JW090')
AND PH1.location = 'A1'
GROUP BY ST.stocknumber,
PH1.location,
PH2.vendornumber
Check the demo here.

How to calculate rank with group by in sql?

Suppose if I have table1 as following
Category Brand Value
A A1 4
B B1 7
C C1 8
A A2 3
B B2 4
C C2 6
A A3 9
B B3 10
C C3 1
A A4 5
Now if I want to calculate rank for each brand but grouped by category how do I go about it?
Something like
Select rank() (over value)
from table
group by category
Expected output is this:
Category Brand Value Rank
A A3 9 1
A A4 5 2
A A1 4 3
A A2 3 4
B B3 10 1
B B1 7 2
B B2 4 3
C C1 8 1
C C2 6 2
C C3 1 3
Maybe you are looking for something like this.
See this official documentation on DENSE_RANK for more details
select brand, category, dense_rank() over(partition by category order by value desc) as dr
from table
You may add a PARTITION BY clause to your RANK() call, specifying the category as the partition.
SELECT RANK() OVER (PARTITION BY category ORDER BY value) rnk
FROM yourTable
ORDER BY category, rnk;

select rows from main table based on highest date in child table between a date range

Sorry for the confusing title.
I've this table:
ApplicantID Applicant Name
-------------------------------
1 Sandeep
2 Thomas
3 Philip
4 Jerin
ALong with this child table which is connected with the above table:
DetailsID ApplicantID CourseName Dt
---------------------------------------------------------------------
1 1 C1 10/5/2014
2 1 C2 10/18/2014
3 1 c3 7/3/2014
4 2 C1 3/2/2014
5 2 C2 10/18/2014
6 2 c3 1/1/2014
7 3 C1 1/5/2014
8 3 C2 4/18/2014
9 3 c3 2/23/2014
10 4 C1 3/15/2014
11 4 C2 2/20/2014
12 4 C2 2/20/2014
I want to get applicantsID, for example, when I specify a date range from
4/20/2014 to 3/5/2014 I should have:
ApplicantID Applicant Name
-------------------------------
3 Philip
4 Jerin
That means the applicants from the main table that must be in the second table and also the highest date of the second table must fall in the specified date range. Hope the scenario is clear.
you can use window analytic function row_number to get applicant with maximum date in the given time range.
select T1.[ApplicantID], [Applicant Name]
from Table1 T1
join ( select [ApplicantID],
ROW_NUMBER() over ( partition by [ApplicantID] order by Dt desc) as rn
from Table2
where Dt BETWEEN '3/5/2014' AND '4/20/2014'
) T
on T1.[ApplicantID] = T.[ApplicantID]
and T.rn =1
You will need to pull the MAX per ApplicantId with a GROUP BY in a sub-query, then JOIN to that result. This should work for you:
Select A.ApplicantId, A.[Applicant Name]
From ApplicantTableName A
Join
(
Select D.ApplicantId, Max(D.Dt) DT
From DetailsTableName D
Group By D.ApplicantId
) B On A.ApplicantId = B.ApplicantId
Where B.DT Between '03/05/2014' And '04/20/2014'

How to Add Order to an existing table?

I have table called Products. Let say this is my table,
ID Name ParentID
-- --- --------
1 a NULL
2 b NULL
3 a1 1
4 a2 1
5 b2 2
6 b2 2
Now I need to add [Order] Column with respect to ParentID,
ID Name ParentID Order
-- --- -------- ----
1 a NULL NULL
2 b NULL NULL
3 a1 1 1
4 a2 1 2
5 b2 2 1
6 b2 2 2
Creating [Order] is trivial but inserting record is a bit tricky part
UPDATE [Products]
SET [Products].[Order] = PTT.[Order]
FROM
[Products]
INNER JOIN (SELECT ID, ROW_NUMBER() OVER (PARTITION BY PT.ParentID ORDER BY ID) AS [Order]
FROM [Products] PT
WHERE PT.ParentID IS NOT NULL) AS PTT ON PTT.ID = [Products].ID

SQL Search for records with missing values in the same table

I have a table (t1) with multiple rows of statuses for different references, one column being a ReferenceID and another column being a StatusID.
t1.ReferenceID - t1.StatusID
A1 - 1
A1 - 2
A1 - 3
A1 - 4
A2 - 1
A2 - 3
A3 - 1
A3 - 3
A4 - 1
A4 - 4
A5 - 2
A5 - 3
I have a second table (t2) which is the list of all available StatusID's
t2.StatusID
1
2
3
4
I need to be able to pull a list of ReferenceID's from t1 where StatusID '1' exists, however it is missing one or more of the other StatusID's in table 2.
i.e. using the above the following referenceID's would be returned:
A2
A3
A4
Don;t know if this will work on SQLAnywhere.
SELECT DISTINCT r.ReferenceID
FROM (SELECT ReferenceID FROM TableName WHERE StatusID = 1 GROUP BY ReferenceID) r
CROSS JOIN (SELECT StatusID FROM TableName GROUP BY StatusID) d
LEFT JOIN TableName a
ON d.StatusID = a.StatusID AND
r.ReferenceID = a.ReferenceID
WHERE a.StatusID IS NULL
ORDER BY r.ReferenceID
SQLFiddle Demo (running in MySQL)