SQL Server : try to find max value of counted row - sql-server

I am using SQL Server 2012 and I have table like this
| Country | Age |
+---------+------+
| SWEDEN | 43 |
| SWEDEN | 17 |
| SWEDEN | 43 |
| SWEDEN | 43 |
| SWEDEN | 17 |
| GERMANY | 17 |
| GERMANY | 17 |
| GERMANY | 17 |
| GERMANY | 44 |
| GERMANY | 44 |
| SWEDEN | 43 |
| SWEDEN | 17 |
| GERMANY | 13 |
| SWEDEN | 17 |
| SWEDEN | 43 |
And I can count ages in the country like this
| Country | Age | CountOfAge |
+----------+------+------------+
| GERMANY | 13 | 1 |
| GERMANY | 17 | 3 |
| SWEDEN | 17 | 4 |
| SWEDEN | 43 | 5 |
| GERMANY | 44 | 2 |
I want max age in country like this
| Country | Age | CountOfAge |
+----------+------+------------+
| GERMANY | 17 | 3 |
| SWEDEN | 43 | 5 |
I tried with this SQL statement:
SELECT
X.country, X.age, X.countOfAge
FROM
(SELECT country, age, COUNT(age) AS countOfAge
FROM MOCK
GROUP BY country, age) X
I count the age but I can't filter the max of counted age

Either RANK() or DENSE_RANK() would provide the same results in this case, but read their documentation to understand the difference in behavior between the two - especially the gaps in numbers returned by RANK().
SELECT
country,
age,
countOfAge
FROM (
SELECT
country,
age,
COUNT(age) AS countOfAge,
DENSE_RANK() OVER (PARTITION BY country ORDER BY COUNT(age) DESC) AS ranking
FROM MOCK
GROUP BY country, age
) X
WHERE ranking = 1;

Related

How to find max(sortnumber) on item code in SQL Server?

I have following SQL Server table ITEM:
+------------+-----------+------+--------+-----------+------------+
| Date | item_code | name | in/out | total_qty | SortNumber |
+------------+-----------+------+--------+-----------+------------+
| 08/07/2019 | 001 | A | -50 | 100 | 8 |
| 07/07/2019 | 001 | A | 50 | 100 | 7 |
| 06/07/2019 | 003 | C | 25 | 25 | 6 |
| 05/07/2019 | 001 | A | 50 | 50 | 5 |
| 04/07/2019 | 002 | B | 100 | 200 | 4 |
| 03/07/2019 | 003 | C | -25 | 0 | 3 |
| 02/07/2019 | 003 | C | 25 | 25 | 2 |
| 01/07/2019 | 002 | B | 100 | 100 | 1 |
+------------+-----------+------+--------+-----------+------------+
I've tried:
select itemcode, max(Sort_Number)
from ITEM
group by item_code
order by item_code asc
but I want result:
+---------------------+-----------+------------------+
| Distinct(item_code) | Total_qty | Max(Sort_Number) |
+---------------------+-----------+------------------+
| 001 | 100 | 8 |
| 002 | 200 | 4 |
| 003 | 25 | 6 |
+---------------------+-----------+------------------+
Can anyone help me?
The below query gives you the desired result -
With cteItem as
(
select item_code, total_qty, SortNumber,
Row_Number() over (partition by item_code order by SortNumber desc) maxSortNumber
from ITEM
)
select item_code, total_qty, SortNumber from cteItem where maxSortNumber = 1
just need to add max(sort_number) to your query
select item_code ,max(total_qty), max(sort_number)
from ITEM
group by item_code
order by item_code asc

Can recursion start from a specific record in a table?

I'm trying to calculate depreciation on vehicles. If there is a rebate on a vehicle, I need to stop the depreciation, factor in the rebaste based on the month it look affect, and resume the depreciation calculation.
A vehicle depreciates at a flat rate of 2% every month with 50 months being the point of 100% depreciation. When a rebate appears, I can stop the depreciation, but I don't know how to make it start again from a certain month.
Below is an example of the table's deprecation up to directly before the rebate:
+----------+-------+------------+--------------+------------+------------+
| Vehicle# | month | depDate | Initial Cost | Monthlydep | totaldep |
+----------+-------+------------+--------------+------------+------------+
| 12451 | 1 | 2015-08-01 | 44953.24 | 899.06 | 899.0648 |
| 12451 | 2 | 2015-09-01 | 44953.24 | 899.06 | 1798.1296 |
| ------- | ----- | ----- | ----- | ----- | ----- |
| 12451 | 42 | 2019-01-01 | 44953.24 | 899.06 | 37760.7216 |
| 12451 | 43 | 2019-02-01 | 44953.24 | 899.06 | 38659.7864 |
+----------+-------+------------+--------------+------------+------------+
Then let's say that a rebate comes in this month (2019-03-01) it needs to be factored in and then the depreciation needs to be recalculated from that month onwards the. How do I restart the depreciation from month 43 instead of it going through everything?
For example let's say that we get a rebate in month 44 for $200 dollars. The table should look like something below:
+----------+-------+------------+--------------+------------+------------+
| Vehicle# | month | depDate | Initial Cost | Monthlydep | totaldep |
+----------+-------+------------+--------------+------------+------------+
| 12451 | 43 | 2019-02-01 | 44953.24 | 899.06 | 38659.7864 |
| 12451 | 44 | 2019-03-01 | 44953.24 | 1099.06 | 39758.8464 |
| 12451 | 45 | 2019-04-01 | 44953.24 | 1099.06 | 40857.9064 |
| 12451 | 46 | 2019-05-01 | 44953.24 | 1099.06 | 41956.9664 |
| 12451 | 47 | 2019-06-01 | 44953.24 | 1099.06 | 43056.0264 |
| 12451 | 48 | 2019-06-01 | 44953.24 | 1099.06 | 44155.0864 |
| 12451 | 49 | 2019-06-01 | 44953.24 | 1099.06 | 45254.1464 |
+----------+-------+------------+--------------+------------+------------+
So month 49 would be the final month because the totalDep is equal to or higher than the initial cost
My sample code is below. If you remove the first cte and the join inner join in the top part of the union then that is the working depreciation calculation:
;With cte As( Select bd.[VehicleID]
,Max(bd.[Month]) As month
,Max(DateAdd(DAY,1,EOMONTH(DepreciationReportDate,-1))) As DepreciationReportDate
,Max(bd.MonthlyDepreciation) As MonthlyDepreciation
,Max(bd.AdjustedPurchaseCost) As AdjustedPurchaseCost
,Max(AccumulatedDepreciation) As AccumulatedDepreciation
From Work.dbo.DepreciationSchedule bd
Group By bd.VehicleID
)
,cte_CreateRows As
(
Select bd.[VehicleID]
,bd.[Month]
,DATEADD(DAY,1,EOMONTH(bd.DepreciationReportDate,-1)) As DepreciationReportDate
,bd.MonthlyDepreciation
,bd.AdjustedPurchaseCost
,bd.AccumulatedDepreciation
From Work.dbo.DepreciationSchedule bd
Inner Join cte cte
On cte.VehicleID = bd.VehicleID
And cte.month = bd.Month
Union All
Select bd.[VehicleID]
,[Month] = Cast(cr.[Month]+1 As int)
,DATEADD(DAY,1,EOMONTH(DateAdd(Month, 1, cr.DepreciationReportDate),-1)) As DepreciationReportDate
,bd.MonthlyDepreciation
,bd.AdjustedPurchaseCost
,AccumulatedDepreciation = cr.AccumulatedDepreciation + cr.MonthlyDepreciation
From Work.dbo.DepreciationSchedule bd
Inner Join cte_CreateRows cr On bd.[VehicleID] = cr.[VehicleID]
Where cr.AccumulatedDepreciation < cr.AdjustedPurchaseCost
And DateAdd(Month,1, DateAdd(DAY,1,EOMONTH(cr.DepreciationReportDate,-1))) < DATEADD(DAY,1,EOMONTH(GetDate(),-1))
)
Select a.VehicleID
,a.Month
,a.DepreciationReportDate
,Cast(a.MonthlyDepreciation As Decimal(12,2)) As 'Monthly Depreciation Expense'
,a.AdjustedPurchaseCost
,a.AccumulatedDepreciation
From [cte_CreateRows] As a
Order By a.VehicleID, a.Month

Sum, Group by and Null

I'm dipping my toes into SQL. I have the following table
+------+----+------+------+-------+
| Type | ID | QTY | Rate | Name |
+------+----+------+------+-------+
| B | 1 | 1000 | 21 | Jack |
| B | 2 | 2000 | 12 | Kevin |
| B | 1 | 3000 | 24 | Jack |
| B | 1 | 1000 | 23 | Jack |
| B | 3 | 200 | 13 | Mary |
| B | 2 | 3000 | 12 | Kevin |
| B | 4 | 4000 | 44 | Chris |
| B | 4 | 5000 | 43 | Chris |
| B | 3 | 1000 | 26 | Mary |
+------+----+------+------+-------+
I don't know how I would leverage Sum and Group by to achieve the following result.
+------+----+------+------+-------+------------+
| Type | ID | QTY | Rate | Name | Sum of QTY |
+------+----+------+------+-------+------------+
| B | 1 | 1000 | 21 | Jack | 5000 |
| B | 1 | 3000 | 24 | Jack | Null |
| B | 1 | 1000 | 23 | Jack | Null |
| B | 2 | 3000 | 12 | Kevin | 5000 |
| B | 2 | 3000 | 12 | Kevin | Null |
| B | 3 | 200 | 13 | Mary | 1200 |
| B | 3 | 1000 | 26 | Mary | Null |
| B | 4 | 4000 | 44 | Chris | 9000 |
| B | 4 | 5000 | 43 | Chris | Null |
+------+----+------+------+-------+------------+
Any help is appreciated!
You can use window function :
select t.*,
(case when row_number() over (partition by type, id order by name) = 1
then sum(qty) over (partition by type, id order by name)
end) as Sum_of_QTY
from table t;

get all rows where column value is same in cassandra cql

This is my table.
cqlsh:sachhya> select * FROM emp;
emp_id | age | emp_name | exp | mobile
--------+-----+--------------+-----+------------
5 | 29 | RAHUL SHARMA | 9 | 2312343123
1 | 24 | SACHHYA | 15 | 9090987876
2 | 14 | SACHHYA | 15 | 9090987876
4 | 22 | ANKUR | 32 | 3213456321
90 | 30 | sumeet | 2 | 91234212
3 | 14 | SACHHYA | 3 | 9090987876
PRIMARY KEY (Partition key) IS emp_id.
I want to display all rows where emp_name is 'SACHHYA'. What command should i use?
Below is the cql query that i am using.
select * FROM emp WHERE emp_name='SACHHYA';
But i am getting an error:
InvalidRequest: Error from server: code=2200 [Invalid query]
message="Predicates on non-primary-key columns (emp_name) are not yet
supported for non secondary index queries"
I have found one solution for my question, We can crate index on 'emp_name' column after that we can use 'emp_name' filter.
EX:
CREATE INDEX NameIndx ON emp (emp_name);
SELECT * from sachhya.emp WHERE emp_name = 'SACHHYA';
My output:
emp_id | age | desegnation | emp_name | exp | mobile
--------+-----+------------------+----------+-----+------------
711 | 22 | Trainee Engineer | SACHHYA | 1 | 9232189345
2 | 24 | Engineer | SACHHYA | 3 | 9033864540
My Table:
emp_id | age | desegnation | emp_name | exp | mobile
--------+-----+------------------+----------+------+------------
5 | 29 | Technical Lead | RAHUL | 9 | 2312343123
10 | 45 | Deleviry Manager | ANDREW | 22 | 9214569345
711 | 22 | Trainee Engineer | SACHHYA | 1 | 9232189345
2 | 24 | Engineer | SACHHYA | 3 | 9033864540
4 | 26 | Engineer | ANKUR | 3 | 3213456321
22 | 20 | Intern | SAM | null | 8858699345
7 | 22 | Trainee Engineer | JACOB | 1 | 9232189345
17 | 28 | Senior Engineer | JACK | 4 | 8890341799
90 | 30 | Senior Engineer | HERCULES | 6 | 9353405163
3 | 32 | Technical Lead | ROSS | 8 | 7876561355

SQL Server : How to subtract values throughout the rows by using values in another column?

I have a table named stock and sales as below :
Stock Table :
+--------+----------+---------+
| Stk_ID | Stk_Name | Stk_Qty |
+--------+----------+---------+
| 1001 | A | 20 |
| 1002 | B | 50 |
+--------+----------+---------+
Sales Table :
+----------+------------+------------+-----------+
| Sales_ID | Sales_Date | Sales_Item | Sales_Qty |
+----------+------------+------------+-----------+
| 2001 | 2016-07-15 | A | 5 |
| 2002 | 2016-07-20 | B | 7 |
| 2003 | 2016-07-23 | A | 4 |
| 2004 | 2016-07-29 | A | 2 |
| 2005 | 2016-08-03 | B | 15 |
| 2006 | 2016-08-07 | B | 10 |
| 2007 | 2016-08-10 | A | 5 |
+----------+------------+------------+-----------+
With the table above, how can I find the available stock Ava_Stk for each stock after every sales?
Ava_Stk is expected to subtract Sales_Qty from Stk_Qty after every sales.
+----------+------------+------------+-----------+---------+
| Sales_ID | Sales_Date | Sales_Item | Sales_Qty | Ava_Stk |
+----------+------------+------------+-----------+---------+
| 2001 | 2016-07-15 | A | 5 | 15 |
| 2002 | 2016-07-20 | B | 7 | 43 |
| 2003 | 2016-07-23 | A | 4 | 11 |
| 2004 | 2016-07-29 | A | 2 | 9 |
| 2005 | 2016-08-03 | B | 15 | 28 |
| 2006 | 2016-08-07 | B | 10 | 18 |
| 2007 | 2016-08-10 | A | 5 | 4 |
+----------+------------+------------+-----------+---------+
Thank you!
You want a cumulative sum and to subtract it from the stock table. In SQL Server 2012+:
select s.*,
(st.stk_qty -
sum(s.sales_qty) over (partition by s.sales_item order by sales_date)
) as ava_stk
from sales s join
stock st
on s.sales_item = st.stk_name;

Resources