SQL - Finding how long the account haven't been paid - sql-server

I have the below table:
+--------+------+---------+------------+
| ID | TEAM | WEEK_NO | Money_paid |
+--------+------+---------+------------+
| 112233 | AA | 201801 | 100 |
| 112233 | BB | 201801 | 0 |
| 112233 | BB | 201802 | 0 |
| 112233 | BB | 201803 | 0 |
| 454545 | AA | 201801 | 100 |
| 658855 | BB | 201802 | 100 |
| 658855 | BB | 201802 | 100 |
| 112233 | BB | 201809 | 0 |
+--------+------+---------+------------+
and I want the result like the below table with this rule that
Count the consecutive week_no.s where the Money_paid is same. It has be in consecutive order:
+--------+------+---------+------------+-------+
| ID | TEAM | WEEK_NO | Money_paid | Count |
+--------+------+---------+------------+-------+
| 112233 | AA | 201801 | 100 | 1 |
| 112233 | BB | 201801 | 0 | 3 |
| 112233 | BB | 201802 | 0 | 3 |
| 112233 | BB | 201803 | 0 | 3 |
| 454545 | AA | 201801 | 100 | 1 |
| 658855 | BB | 201802 | 100 | 1 |
| 112233 | BB | 201809 | 0 | 1 |
+--------+------+---------+------------+-------+
So far I have tried many methods but none of them is any close to the desired result.
select top 10
Concat(TEAM, ID) AS Concatbu_ac, count(*)
from
(select
*,
(row_number() over (order by week_no) -
row_number() over (partition by Concat(team, ID) order by week_no)
) as group5
from
table5) t
group by
group5, Concat(team, ID);

If I understand correctly, you want to count the week based on amount paid by ID & Team. The idea is to count the record group by ID, Team, Money_Paid, then self join by unique column. Hope this answer your question.
DECLARE #dataset TABLE (
ID INT,
Team VARCHAR(10),
Week_No INT,
Money_Paid INT
)
INSERT INTO #dataset SELECT 112233, 'AA', 201801, 100
INSERT INTO #dataset SELECT 112233, 'BB', 201801, 0
INSERT INTO #dataset SELECT 112233, 'BB', 201802, 0
INSERT INTO #dataset SELECT 112233, 'BB', 201803, 0
INSERT INTO #dataset SELECT 454545, 'AA', 201801, 100
INSERT INTO #dataset SELECT 658855, 'BB', 201802, 100 --duplicate
INSERT INTO #dataset SELECT 658855, 'BB', 201802, 100 --duplicate
INSERT INTO #dataset SELECT 112233, 'BB', 201809, 0
--week count
SELECT
ds.*,
x.WeekCount
FROM #dataset ds
JOIN (
SELECT
ID,
Team,
COUNT(Week_No) AS WeekCount
FROM #dataset
GROUP BY ID, Team, Money_Paid
) x
ON ds.ID = x.ID
AND ds.Team = x.Team
ORDER BY ID, Team, Week_No
--week to date
SELECT
ds.*,
COUNT(*) OVER (PARTITION BY ID, Team, Money_Paid ORDER BY ID, Team, Week_No) AS WeekToDate
FROM #dataset ds

Related

Assign value into specific column using Pivot or Unpivot

I have a table with below structure:
+-------+-----------+--------+----------+--------+
| RefNo | TranType | Code | Remarks | Amount |
+-------+-----------+--------+----------+--------+
| 1 | BD | 400201 | abcc dfr | 200 |
| 1 | BD | 400202 | abcc dfr | 200 |
| 2 | BD | 400204 | defrt | 300 |
| 2 | BD | 400205 | defrt | 300 |
+-------+-----------+--------+----------+--------+
I need to transpose these values to the below format:
+-------+--------+--------+----------+----------+--------+
| RefNo | Code1 | Code2 | TranType | Remarks | Amount |
+-------+--------+--------+----------+----------+--------+
| 1 | 400201 | 400202 | BD | abcc dfr | 200 |
| 2 | 400204 | 400205 | BD | defrt | 300 |
+-------+--------+--------+----------+----------+--------+
You don't need to use PIVOT, you can do it using a simple query.
SELECT t1.refno,
t1.code AS Code1,
t2.code AS Code2,
t1.trantype,
t1.amount
FROM #table t1
INNER JOIN #table t2
ON t1.refno = t2.refno
AND T1.code < T2.code
Online Demo
You can try the following query.
;WITH Tab (RefNo,Code,TranType,Remarks,Amount,rowno)
AS
(SELECT T.RefNo
, T.Code
,TranType
,Remarks
,Amount
, RN = ROW_NUMBER() OVER (PARTITION BY T.RefNo ORDER BY T.Code )
FROM Table1 T)
SELECT RefNo,Code1 = MAX( CASE WHEN N.rowno=1 THEN N.Code ELSE 0 END ),
Code2 = MAX( CASE WHEN N.rowno=2 THEN N.Code ELSE 0 END ) ,
TranType,Remarks,Amount FROM Tab n
GROUP BY N.RefNo,TranType,Remarks,Amount

Need to split entry points with the number of user comes first

+------------+-------+---------+---------------+
| STudent_ID | Marks | Subject | EntryPoints |
+------------+-------+---------+---------------+
| 1 | 50 | Maths | 10 |
| 2 | 50 | Maths | 10 |
| 3 | 45 | Maths | 10 |
| 1 | 30 | History | 20 |
| 2 | 30 | History | 20 |
| 3 | 30 | History | 20 |
+------------+-------+---------+---------------+
Expected output:
+------------+-------+---------+---------------+
| student_id | Marks | Subject | TotalPoints |
+------------+-------+---------+---------------+
| 1 | 50 | Maths | 5 |
| 2 | 50 | Maths | 5 |
| 1 | 30 | History | 6.66 |
| 2 | 30 | History | 6.66 |
| 3 | 30 | History | 6.66 |
+------------+-------+---------+---------------+
Total points calculation
For maths Entry points is 10 and number of student scored maximum is 2 so 10/2 = 5
for history Entry points is 20 and number of student scored maximum is 3 so 20/3 = 6.66
Query I tried:
select student_id,marks,subject from
(
select student_id,marks,subject,dense_rank() over ( partition by subject order by marks desc) rn from test
) t
where rn=1
Output:
+------------+-------+---------+
| Student_id | Marks | Subject |
+------------+-------+---------+
| 1 | 50 | Maths |
| 2 | 50 | Maths |
| 1 | 30 | History |
| 2 | 30 | History |
| 3 | 30 | History |
+------------+-------+---------+
I am not getting how to get the total points column in my query
I am assuming that the max score is the max among all the marks with the same subject.
SELECT
Student_ID
,Marks
,T.Subject
,CONVERT(decimal(18, 2),
CONVERT(float, EntryPoints)/
CONVERT(float, COUNT(*) OVER(PARTITION BY T.Subject))) as 'TotalPoints'
FROM #T T
INNER JOIN (SELECT DISTINCT Subject, MAX(Marks) OVER(PARTITION BY Subject)
as Max_Marks FROM #T) Scores
ON T.Subject = Scores.Subject
WHERE Marks = Scores.Max_Marks
ORDER BY Marks DESC, Student_ID
You can use Group by with your query for getting the count of subject, then join the result with the same query.
as next:-
Select a.student_id,a.marks,a.subject,
Cast(a.EntryPoints as decimal ) / cast(b.CountPerSubject as decimal) TotalPoints
from
(
select student_id,marks,subject ,EntryPoints
from
(
select student_id,marks,
subject, EntryPoints,
dense_rank() over ( partition by subject order by marks desc) rn
from test
) t
where rn=1
) a
Left Join
(
select subject, count(subject) CountPerSubject
from
(
select student_id,marks,subject ,EntryPoints
from
(
select student_id,marks,
subject, EntryPoints,
dense_rank() over ( partition by subject order by marks desc) rn
from test
) t
where rn=1 ) c
group by subject) b
on a.subject = b.subject

SQL Server: Returning rows with multiple and distinct values

I've been working on this issue for the last day and a half and just can't seem to find another question on here that works for my code.
I have a table here:
Table_D
Policynumber| EntryDate | BI_Limit | P remium
------------------------------------------------------
ABCD100001 | 5/1/16 | 15/30 | 919
ABCD100001 | 5/13/16 | 15/30 | 1008
ABCD100002 | 5/24/16 | 100/300 | 1380
ABCD100003 | 5/30/16 | 25/50 | 1452
ABCD100003 | 6/2/16 | 25/50 | 1372
ABCD100003 | 6/4/16 | 30/60 | 951
ABCD100004 | 6/11/16 | 100/300 | 1038
ABCD100005 | 6/22/16 | 100/300 | 1333
ABCD100005 | 7/2/16 | 50/100 | 1208
ABCD100006 | 7/10/16 | 250/500 | 1345
ABCD100007 | 7/18/16 | 15/30 | 996
in which I'm trying to extract rows in which a policynumber has multiple listings and a different BI_Limit. So the output should be:
Output
Policynumber | EntryDate | BI_Limit | Premium
---------------------------------------------------
ABCD100003 | 5/30/16 | 25/50 | 1452
ABCD100003 | 6/2/16 | 25/50 | 1372
ABCD100003 | 6/4/16 | 30/60 | 951
ABCD100005 | 6/22/16 | 100/300 | 1333
ABCD100005 | 7/2/16 | 50/100 | 1208
I'm storing Policynumber as VARCHAR(Max), EntryDate as DATE, BI_Limit as VARCHAR(Max), and Premium as INTEGER.
The code I've want to say should work would be something along the lines of:
SELECT * FROM Table_D
WHERE BI_Limit IN (
SELECT BI_Limit
FROM Table_D
GROUP BY BI_Limit
HAVING COUNT(DISTINCT BI_Limit)>1);
But this returns nothing for me. Can anyone help to show me what I'm doing wrong? Thank you.
You could also try exists
select a.*
from Table_D a
where
exists (
select 1
from Table_D b
where a.Policynumber = b.Policynumber
and a.BI_Limit <> b.BI_Limit
)
SELECT d.*
FROM ( -- find the policy number with multiple listing and diff BI_Limit
SELECT PolicyNumber
FROM TableD
GROUP BY PolicyNumber
HAVING count(*) > 1
AND MIN (BI_Limit) <> MAX (BI_Limit)
) m -- join back the Table_D to for other information
INNER JOIN Table_D d
ON m.PolicyNumber = d.PolicyNumber

How to rename column before unpivot? SQL Server

Help I want to rename a column before using the unpivot method
My table is like this:
List item
id| value| ENE| FEB| MAR| ABR| MAY
1 | dsads|2000|2334|2344|2344|2344
after unpivot I get something like this
id| value| month| amount
1 | dads| ENE | 2000
2 | sadf| FEB | 2334
but I want something like this
id| value| month| amount
1 | dads| 01 | 2000
2 | sadf| 02 | 2334
This is my query
select
[año], [Empresa], [Region], [Suc], [CC], [Cuenta],
[Subcuenta], [Descripcion], Periodo, Importe
from
(select * from [dbo].['P Cargado$']) S
unpivot
(Importe for Periodo in
([ENE], [FEB], [MAR], [ABR], [MAY], [JUN], [JUL], [AGO], [SEP],[OCT], [NOV], [DIC])
) AS unpvt;
If you use cross apply(values ..) to unpivot, you could do so like this:
select t.id, t.value, x.*
from t
cross apply (values (1,ene),(2,feb),(3,mar),(4,abr),(5,may)) x (Mnth,Amount)
rextester demo: http://rextester.com/SZDP50356
returns:
+----+-------+------+--------+
| id | value | Mnth | Amount |
+----+-------+------+--------+
| 1 | dsads | 1 | 2000 |
| 1 | dsads | 2 | 2334 |
| 1 | dsads | 3 | 2344 |
| 1 | dsads | 4 | 2344 |
| 1 | dsads | 5 | 2344 |
+----+-------+------+--------+

Find max and min of a column and update the first column sql server

Based on the product and product key, update the column ord_by. There should be only one min and max for a product and product_key .
E.g: Table
+-------------+---------+-------+--------+
| Product_key | product | price | ord_by |
+-------------+---------+-------+--------+
| 1 | ABC | 10 | |
| 1 | ABC | 10 | |
| 1 | ABC | 20 | |
| 1 | ABC | 100 | |
| 1 | ABC | 100 | |
| 2 | EFG | 20 | |
| 2 | EFG | 40 | |
| 3 | ABC | 100 | |
+-------------+---------+-------+--------+
Expected output:
+-------------+---------+-------+--------+
| Product_key | product | price | ord_by |
+-------------+---------+-------+--------+
| 1 | ABC | 10 | Min |
| 1 | ABC | 10 | Mid |
| 1 | ABC | 20 | Mid |
| 1 | ABC | 100 | Mid |
| 1 | ABC | 100 | Max |
| 2 | EFG | 20 | Min |
| 2 | EFG | 40 | Max |
| 3 | ABC | 100 | None |
+-------------+---------+-------+--------+
My try :
;WITH ord_cte
AS (
SELECT product
,product_key
,max(price) as max_price
,min(price) as min_price
FROM t_prod_ord
group by product,product_key
)
UPDATE t1
SET ord_by = case
when t2.max_price =t2.min_price then 'none'
when t2.max_price=t1.price then 'max'
when t2.min_price=t1.price then 'min'
else 'mid' end
FROM t_prod_ord t1
INNER JOIN ord_cte t2 ON t1.product_key = t2.product_key and t1.product=t2.product
using this query it is updating more than one max and min value for column ord_by.
Generate row number for each Product_key order by Price in both ASC and DESC order. Then use the row number in CASE statement to find the Min/Max values
Count() Over() aggregate window function will help you find the total count of each Product_key which we can use it for finding None
Here is one way
;WITH cte
AS (SELECT *,
Row_number()OVER(PARTITION BY Product_key ORDER BY price) AS Min_KEY,
Row_number()OVER(PARTITION BY Product_key ORDER BY price DESC) AS Max_KEY,
Count(1)OVER(partition BY Product_key) AS cnt
FROM Yourtable)
SELECT Product_key,
product,
price,
CASE
WHEN cnt = 1 THEN 'None'
WHEN Min_KEY = 1 THEN 'Min'
WHEN Max_Key = 1 THEN 'Max'
ELSE 'Mid'
END
FROM cte
Another way to do with out cte...
SELECT [Product_key],
[product],
[price],
CASE
WHEN Max(RN)
OVER(
PARTITION BY PRODUCT_KEY, PRODUCT
)=1 AND RN=1 THEN 'NONE'
WHEN Min(RN)
OVER(
PARTITION BY PRODUCT_KEY, PRODUCT
) = RN THEN 'MIN'
WHEN Max(RN)
OVER(
PARTITION BY PRODUCT_KEY, PRODUCT
) = RN THEN 'MAX'
ELSE 'MID'
END ORDER_BY
FROM (SELECT *,
Row_number()
OVER(
PARTITION BY PRODUCT_KEY, PRODUCT
ORDER BY PRICE) RN
FROM TABLE1)Z

Resources