How to SUM column if same value - sql

I have query to SUM and COUNT my table, but i have trouble, i want to SUM column name after COUNT it.
This is my table...
id no_reg name date qty
1 REG01 T-212-BS 2019-05-03 1
2 REG01 T-212-BS 2019-05-03 1
3 REG01 T-212-BS 2019-05-03 1
4 REG01 T-212-BA 2019-05-03 1
5 REG02 T-111-AA 2019-05-04 1
6 REG03 T-111-AB 2019-05-04 1
I create query....
SELECT no_reg, COUNT(DISTINCT name) AS Name_qty, date, SUM(qty) AS qty
FROM part
GROUP BY no_reg, name, date, qty
and result of query after execution...
no_reg Name_qty date qty
REG01 1 2019-05-03 1
REG01 1 2019-05-03 3
REG02 1 2019-05-04 1
REG03 1 2019-05-04 1
But, I want results like this...
no_reg Name_qty date qty
REG01 2 2019-05-03 4
REG02 1 2019-05-04 1
REG03 1 2019-05-04 1

No need to group by name, even if you're using it in your distinct statement.
SELECT no_reg, COUNT(DISTINCT name) AS Name_qty, date, SUM(qty) AS qty
FROM part
GROUP BY no_reg, date

You're grouping by qty, so any rows that do not have the same qty will be aggregated separately. Since qty is used in an aggregate function, you can remove it from the group by and it should give you the expected results
SELECT no_reg, COUNT(DISTINCT name) AS Name_qty, date, SUM(qty) AS qty
FROM part
GROUP BY no_reg, date
EDIT:
I also noticed that name was included in the group by. You can remove it too since it is used in the count aggregate

Related

Grouping then max on MSSQL Query

I have two tables as follows.
Table 1:
ID
ArtNumber
Date
Price
1
Article1
07.05.2022
100.00
2
Article2
07.05.2022
100.00
3
Article1
10.05.2022
100.00
4
Article2
10.05.2022
100.00
Table 2
ID
ArtNumber
Price
1
Article1
80.00
2
Article2
120.00
I want for Table 1 the newest (Date) price for each ArtNumber. But also want to then check if the price is more than in Table 2. (Table1.Price<Table2.Price)
Expected result:
ArtNumber
Price
Article2
120.00
I have tried a lot of GROUP BY, ORDER BY, MAX() and DISTINCT combinations without success.
You can use a simple greatest-n-per-group query:
with cte as (
select *, row_number() over (partition by artnumber order by date desc) as rn
from table1
)
select *
from cte
join table2 on cte.artnumber = table2.artnumber
where rn = 1 and cte.price < table2.price

Find Column With Max on Other Column Grouping By Another Column

I have a table like this:
Id - ItemId - Price - SalesId - Date
1 12 99.99924 21899234 2025-01-01 00:00:00.000000
2 123 12.34567 348923 2021-01-01 00:00:00.000000
3 1234 1234.5 3321234 2022-01-01 00:00:00.000000
4 12345 3.3246 2154234 2023-01-01 00:00:00.000000
5 1234 451.234 3423 2020-02-01 00:00:00.000000
6 12345 0.989 71112357 2020-09-15 20:20.10.000000
7 123 3435.3 71112357 2020-09-14 20:10:12.000000
I am trying to find the Price of an Item with latest Date. For example, if we tried to find ItemId = 1234, the one with the latest date is this 2022-01-01 00:00:00.000000 that has Id = 3, it has the price of 1234.5. That's what I'm trying to find by this query, the price of this item.
I am a beginner to SQL and tried the following query, but it gives me this error:
select "ItemId",
max("Date"),
"Price"
from "Products"
group by "ItemId"
[42803] ERROR: column "Products.Price" must appear in the GROUP BY clause or be used in an aggregate function
I appreciate any help here. Thank you!
In Postgres, you can use distinct on:
select distinct on ("ItemId") p.*
from "Products" p
order by "ItemId", "Date" desc;
Note: If you are learning SQL, don't use double quotes for string and column names.
You can try using row_number()
select * from
(
select ItemId,Date,Price,row_number() over(partition by itemid order by date desc) as rn
from Products
)A where rn=1

Calculating Daily Change and New Salespersons

I have a SALES table with Person, Date and Qty:
Person Date Qty
Bob 2016-08-01 5
Bob 2016-08-02 2
Bob 2016-08-03 6
Bob 2016-08-04 4
Jim 2016-08-01 1
Jim 2016-08-02 3
Jim 2016-08-03 2
Jim 2016-08-04 2
Sheila 2016-08-03 9
Sheila 2016-08-04 12
I would like to produce 3 outputs
1) The Daily change in total Qty for the Persons who were selling the prior day:
Date Qty Change Pct Change
2016-08-01 0 0 0.00
2016-08-02 5 -1 -16.66
2016-08-03 8 3 60.00
2016-08-04 18 1 5.88
Note that 8/1/16 is the first day in my dataset, so total = 0 since no SalesPerson was selling the prior day. Also note that Sheila started selling on 8/3, which means here 8/3 sales do not figure into the 8/3 qty or change. However, when determining the 8/4 change, Sheila's 8/3 sales of 9 units are used to determine the correct total change of 1 unite for 8/4.
2) I want to break out the totals for new SalesPersons each day on one line per day. If no new Salespersons are added, then the date would show zeros.
Date New Qty
2016-08-01 6
2016-08-02 0
2016-08-03 9
2016-08-04 0
Since 8/1 was the first day of selling for anyone, both sales for Bob and Jim are included in the New Qty of 6 for 8/1.
3) The final output shows detail for #2, such as the date that a new SalesPerson started selling and the quantity they sold on that day.
Date Person New Qty
2016-08-01 Bob 5
2016-08-01 Jim 1
2016-08-03 Sheila 9
Are these 3 outputs possible in SQL Server?
You can use LAG() if you are using sql server 2012 or above. You got the "change". You can figure out the rest.
Query #1:
SELECT
dt.DateVal,
SUM(CASE WHEN dt.PreviousQuota = 0 THEN 0 ELSE dt.PreviousQuotadd END) Change
FROM
(
SELECT
Id,
Person,
DateVal,
Qty,
LAG(Qty, 1,0) OVER ( PARTITION BY Person ORDER BY DateVal) AS PreviousQuota ,
LEAD(Qty, 1,0) OVER ( PARTITION BY Person ORDER BY DateVal) AS NextQuota ,
LAG(Qty, 1,0) OVER ( PARTITION BY Person ORDER BY DateVal) AS PreviousQuotad ,
(Qty - LAG(Qty, 1,0) OVER ( PARTITION BY Person ORDER BY DateVal)) AS PreviousQuotadd
FROM Table1
) AS dt
Here is the Fiddlle link.
I solved the following queries:
Query #2:
WITH CTE_1 AS
(Select DISTINCT Date FROM [master].[dbo].[Sales] GROUP BY Date)
, CTE_2 AS
(select Person,Date,ROW_NUMBER() OVER(Partition By Person Order By Date) as RowNum, SUM(Qty) as [PersonDailySum]
FROM [master].[dbo].[Sales]
GROUP BY Person,Date)
,CTE_3 AS(
SELECT T0.date, SUm([PersonDailySum]) As [New Qty]
FROM CTE_1 T0
LEFT JOIN CTE_2 T1
ON T0.Date = T1.date AND T1.RowNum = 1
GROUP BY T0.Date)
SELECT Date, ISNULL([New Qty],0) AS [New Qty] FROM CTE_3
Query #3
SELECT Date,Person,SUM([PersonDailySum]) AS [New Qty] FROM (
select Person,Date,ROW_NUMBER() OVER(Partition By Person Order By Date) as RowNum, SUM(Qty) as [PersonDailySum]
FROM [master].[dbo].[Sales]
GROUP BY Person,Date) T0
WHERE T0.RowNum = 1
GROUP BY Date,Person

Group orders by date

I have this table food_order which contains data like:
ID food_name order_id order_month
1 apple 123 2017-02
2 apple 345 2017-11
3 pear 4656 2017-02
4 orange 5778 2017-09
5 apple 454 2017-02
What I need to have is a table that shows the number of orders for a specific food in a specific month.
I.e
ID food name nr_orders month
1 apple 2 2017-02
I need to do this using joins and no other functions over there.
Help would be appreciated
Here you could try SQL Query for Microsoft SQL Server :
SELECT MIN(id) [ID],
food_name [food name],
COUNT(order_id) [nr_orders],
order_month
FROM #TM
GROUP BY food_name,
order_month
ORDER BY ID;
Result :
ID food name nr_orders order_month
1 apple 2 2017-02
2 apple 1 2017-11
3 pear 1 2017-02
4 orange 1 2017-09
Note : order_month datatype is VARCHAR
You can use like this
SELECT food_name, SUM(quantity) as quantity, SUM(amount) as amount, MONTH(date) as Month
FROM food_order
GROUP BY food_name, MONTH(date)

SQL query to group by data but with order by clause

I have table booking in which I have data
GUEST_NO HOTEL_NO DATE_FROM DATE_TO ROOM_NO
1 1 2015-05-07 2015-05-08 103
1 1 2015-05-11 2015-05-12 104
1 1 2015-05-14 2015-05-15 103
1 1 2015-05-17 2015-05-20 101
2 2 2015-05-01 2015-05-02 204
2 2 2015-05-04 2015-05-05 203
2 2 2015-05-17 2015-05-22 202
What I want is to get the result as.
1 ) It should show output as Guest_no, Hotel_no, Room_no, and column with count as number of time previous three column combination repeated.
So OutPut should like
GUEST_NO HOTEL_NO ROOM_NO Count
1 1 103 2
1 1 104 1
1 1 101 1
2 2 204 1
etc. But I want result to in ordered way e.g.: The output should be order by bk.date_to desc
My query is as below its showing me count but if I use order by its not working
select bk.guest_no, bk.hotel_no, bk.room_no,
count(bk.guest_no+bk.hotel_no+bk.room_no) as noOfTimesRoomBooked
from booking bk
group by bk.guest_no, bk.hotel_no, bk.room_no, bk.date_to
order by bk.date_to desc
So with adding order by result is showing different , because as I added order by date_to column so i have to add this column is group by clause too which will end up in different result as below
GUEST_NO HOTEL_NO ROOM_NO Count
1 1 103 1
1 1 104 1
1 1 103 1
1 1 101 1
2 2 204 1
Which is not the output I want.
I want these four column but with order by desc of date_to column and count as no of repetition of first 3 columns
I think a good way to do this would be grouping by guest_no, hotel_no and room_no, and sorting by the maximum (i.e. most recent) booking date in each group.
SELECT
guest_no,
hotel_no,
room_no,
COUNT(1) AS BookingCount
FROM
booking
GROUP BY
guest_no,
hotel_no,
room_no
ORDER BY
MAX(date_to) DESC;
Maybe this is what you're looking for?
select
guest_no,
hotel_no,
room_no,
count(*) as Count
from
booking
group by
guest_no,
hotel_no,
room_no
order by
min(date_to) desc
Or maybe max() instead of min(). SQL Fiddle: http://sqlfiddle.com/#!6/e684c/3
You could try this.
select t.* from
(
select bk.guest_no, bk.hotel_no, bk.room_no, bk.date_to,
count(*) as noOfTimesBooked from booking bk
group by bk.guest_no, bk.hotel_no, bk.room_no, bk.date_to
) t
order by t.date_to
You will also have to select date_to and then group the result by it.
If you use 'group by' clause, SQL Server doesn't allow you to use 'order by'. So you can make a sub query and use 'order by' in the outer query.
SELECT * FROM
(select bk.guest_no,bk.hotel_no,bk.room_no
,count(bk.guest_no+bk.hotel_no+bk.room_no) as noOfTimesRoomBooked,
(SELECT MAX(date_to) FROM booking CK
WHERE CK.guest_no=BK.guest_no AND bk.hotel_no=CK.bk.hotel_no
bk.room_no=CK.ROOM_NO ) AS DATEBOOK
from booking bk
group by bk.guest_no,bk.hotel_no,bk.room_no,bk.date_to) A
ORDER BY DATEBOOK
IT MIGHT HELP YOU