I have data looks like this:
Order No. Name Date Unit Price Freight
001 ABC 1-16 232 25
001 ABC 1-16 55 25
001 ABC 1-16 156 25
002 DEF 2-5 478 16
002 DEF 2-5 356 16
I am trying to let freight cost only show once in my table, the result would look like:
Order No. Name Date Unit Price Freight
001 ABC 1-16 232 25
001 ABC 1-16 55 0
001 ABC 1-16 156 0
002 DEF 2-5 478 16
002 DEF 2-5 356 0
Please help me with this
Here is a query to get what you want:
SELECT
order_no, name, theDate, unit_price,
case
when row_number() OVER (PARTITION by order_no ORDER BY order_no) = 1 then freight
else 0
end as freight
from yourTable
This looks at all rows for each order number and provides the row number. If it's row 1 of that order it uses the values of the freight column, otherwise it uses 0.
Note that I'm assuming that the freight value is the same across all rows for the same order number.
Related
My data is as follows:
ID DATE_ADM DRUG_NAME DRUG_VALUE
2 2010-12-01 05:00:00.00 FORMULA VI 50
2 2010-12-01 10:30:00.00 FORMULA VI 40
2 2010-12-02 01:00:00.00 FORMULA V 20
1 2014-01-01 11:00:00.00 FORMULA V 40
1 2014-01-01 23:00:00.00 FORMULA IV 80
1 2014-01-02 11:00:00.00 FORMULA IV 80
I want to calculate the Average value per day for a similar drug name. So that I end up with a table as follows:
ID DATE_ADM DRUG_NAME DRUG_VALUE AVG_DAY_VALUE
2 2010-12-01 05:00:00.00 FORMULA VI 50 45
2 2010-12-01 10:30:00.00 FORMULA VI 40 45
2 2010-12-02 01:00:00.00 FORMULA V 20 20
1 2014-01-01 11:00:00.00 FORMULA V 40 60
1 2014-01-01 23:00:00.00 FORMULA IV 80 60
1 2014-01-02 11:00:00.00 FORMULA IV 80 80
Joel Coehoorn suggested the following to calculate the datediff, and I adapted it to something like this
datediff(day, date, coalesce(lag(date) over(partition by ID, DRUG_NAME order by id, date))) as day_diffs
avg(drug_value) over(partition by id, drug_name, day_diffs) as AVG_DAY_VALUE
No Luck so far. Any help would be appreciated.
Your desired results would seem to be just:
select *,
Avg(drug_value) over(partition by id, Convert(date,date)) Avg_Day_Value
from t
order by id desc, date;
Hey i have a table like this
Product_name Rate Cost GST_percentage Recipt_no Amount Final_Amount ID Description GST_price Quantity OrderID Discount Net_Unit_Price Stock_Pending Payment_Pending
SINGTEL DATA + EZ $10 1.5 GB 7 DAYS 10 120.00 5 1 120.00 126 1 A 6.00 12 ODR1 0.00 10.00 Received Paid
SINGTEL DATA + EZ $10 1.5 GB 7 DAYS 12 180.00 0 2 180.00 180.00 2 A 0.00 15 ODR2 0.00 12.00 NULL NULL
SINGTEL DATA + EZ $8 CHINA 888 10 120.00 0 2 120.00 120.00 3 B 0.00 12 ODR2 0.00 10.00 NULL NULL
and i want to show the final_Amount column value groupped by order Id.then i want to show the final_amount for those which is Payment_Pending status is not null but i can't get the correct result.
Note:
i got a result as
query:
SELECT [OrderID],
SUM(convert(float,[Final_Amount])) as Final_Amount,
(select sum(convert(float,Final_Amount)) as Final_Amount
from Purchase_Order
where Payment_Pending is not null) as paid
FROM [Purchase_Order]
group by [OrderID]
order by OrderID desc
OrderID Final_Amount paid
ODR2 300 126
ODR1 126 126
but i want like this
OrderID Final_Amount paid
ODR2 300 0
ODR1 126 126
(Because ODR2 Payment_Pending Column filled with null)
Probably your sub-query is wrong. It need to include a reference to OrderId of main query
SELECT [OrderID],
SUM(convert(float,[Final_Amount])) as Final_Amount,
(select sum(convert(float,Final_Amount)) as Final_Amount
from Purchase_Order x
where x.Payment_Pending is not null
and x.OrderId = p.OrderId) as paid
FROM [Purchase_Order] p
group by [OrderID]
order by OrderID desc
I have these tables.
Main table
[key] [CategoryID]
AAAA 100
BBBB 100
CCCC 101
DDDD 102
EEEE 201
FFFF 202
GGGG 202
etc.
Category lookup
[CategoryID] [Category] [Subcategory]
100 Category1 Subcategory1
101 Category1 Subcategory2
102 Category1 Subcategory3
103 Category1 Subcategory4
200 Category2 SubcategoryA
201 Category2 SubcategoryB
202 Category2 SubcategoryC
etc.
Status lookup
[StatusID] [Description]
0 New
500 Accepted
501 Rejected
Status history
[key] [StatusID] [date]
AAAA 0 2017-01-01
BBBB 0 2017-01-01
CCCC 0 2017-01-01
DDDD 0 2017-01-01
EEEE 0 2017-01-01
FFFF 0 2017-01-01
GGGG 0 2017-01-01
AAAA 500 2017-01-02
BBBB 501 2017-01-02
EEEE 501 2017-01-02
FFFF 500 2017-01-02
BBBB 500 2017-01-03
EEEE 500 2017-01-03
etc.
I'd like to get a monthly summary of the results (which is emailed out). Right now I'm building the summary table in the code. I'd like to learn how to do it in SQL, but I don't really know where to start.
Final table where the totals are based on the last [Status History] value and ordered by [Total] DESC.
[Category] [Subcategory] [New] [Accepted] [Rejected] [Total]
Category1 Subcategory1 13 8 2 23
Category2 Subcategory3 10 4 6 20
Category1 Subcategory2 5 8 4 17
I've tried to look at PIVOT to do this, but I don't understand how to do it with the joins and with getting only the last status history value.
I think this is what you're after. I recreated your data and tested it out, but I definitely had to make one or two assumptions about the relationships involved. Try it and let me know:
select Category,
Subcategory,
sum(case when description = 'New' then 1 else 0 end) as New,
sum(case when description = 'Accepted' then 1 else 0 end) as Accepted,
sum(case when description = 'Rejected' then 1 else 0 end) as Rejected,
count(*) as Total
from
(select tB.Category, tB.Subcategory, status_lookup.Description
from status_history inner join (select my_key, max(status_date) as lastdate
from status_history
group by my_key) tA on status_history.my_key = tA.my_key
and status_history.status_date = tA.lastdate
inner join status_lookup on status_history.StatusID = status_lookup.StatusID
inner join (select main.my_key, category_lookup.Category, category_lookup.Subcategory
from main inner join category_lookup on main.CategoryID = category_lookup.CategoryID) tB on status_history.my_key = tB.my_key) tC
group by Category, Subcategory
I renamed your [key] column my_key, and called the tables main, category_lookup, status_lookup, and status_history respectively.
I have a list of customers that can have a single, or multiple, service listed. In the table that houses the changes over time there is an indicator of 'Added' or 'Removed'.
What I need: determine those service(s) that are currently active, if at all.
Here is a sample set of data:
CUST_ID SRV_ID STATUS ACTION_DATE
12345 102 Added 1/31/17 10:15
12345 189 Added 4/18/17 15:37
12345 189 Removed 4/21/17 14:08
12345 194 Added 5/2/17 14:43
12345 194 Removed 5/5/17 10:02
12345 194 Added 5/5/17 13:06
12345 69 Added 4/19/17 9:36
12345 69 Removed 5/2/17 14:43
12345 73 Added 4/20/17 10:21
12345 73 Removed 4/25/17 11:20
12345 95 Added 5/4/17 9:48
12345 95 Removed 5/4/17 10:05
Records to be returned: 102 on 1/31/17 10:15 and 194 on 5/5/17 13:06
You can find the latest row for each cust_id and serv_id using top 1 with ties and window function row_number and then filter those with status "Added":
select *
from (
select top 1
with ties *
from your_table
order by row_number() over (
partition by cust_id, srv_id
order by action_date desc
)
) t
where status = 'Added'
Produces:
CUST_ID SRV_ID STATUS ACTION_DATE
12345 102 Added 2017/01/31 10:15
12345 194 Added 2017/05/05 13:06
Demo
Like this:
SELECT SRV_ID
FROM YourTable
GROUP BY SRV_ID
HAVING MAX(CASE WHEN STATUS='Added' THEN ACTION_DATE END)
> MAX(CASE WHEN STATUS='Removed' THEN ACTION_DATE END)
I am working on a small reporting application. I have two tables
Agent Table Data
AgentID AgentName
------- ---------
1001 ABC
1002 XYZ
1003 POI
1004 JKL
Report Table Data
ReportID AgentId Labor Mandays Amount SubmitDate
-------- ------- ----- ------- ------ ----------
1 1001 30 10 5000 11/12/2011
2 1001 44 18 8000 11/14/2011
3 1002 33 75 3022 11/12/2011
4 1001 10 10 1500 11/14/2011
5 1002 10 10 1800 11/14/2011
6 1001 10 10 1400 11/14/2011
7 1003 40 40 1500 11/14/2011
8 1003 40 40 1800 11/14/2011
I want to generate a report which gives us output like
ReportID AgentId Labor Mandays Amount SubmitDate
-------- ------- ----- ------- ------ ----------
1 1001 30 10 5000 11/12/2011
3 1002 33 75 3022 11/12/2011
6 1001 10 10 1400 11/14/2011
5 1002 10 10 1800 11/14/2011
8 1003 40 40 1800 11/14/2011
Thanks in Advance
You didn't mention what VERSION of SQL Server you're using - if you're on 2005 or newer, you can use a CTE (Common Table Expression) with the ROW_NUMBER function:
;WITH LastPerAgent AS
(
SELECT
AgentID, ReportID, Labor, Mandays, Amount, SubmitDate,
ROW_NUMBER() OVER(PARTITION BY AgentID,SubmitDate
ORDER BY ReportID DESC) AS 'RowNum'
FROM dbo.Report
)
SELECT
AgentID, ReportID, Labor, Mandays, Amount, SubmitDate,
FROM LastPerAgent
WHERE RowNum = 1
This CTE "partitions" your data by AgentID and SubmitDate, and for each partition, the ROW_NUMBER function hands out sequential numbers, starting at 1 and ordered by ReportID DESC - so the "last" row (with the highest ReportID) for each (AgentID, SubmitDate) pair gets RowNum = 1 which is what I select from the CTE in the SELECT statement after it.
PS: this doesn't work 100% on your input data, since you've not defined how to group and how to eliminate rows.... you might need to adapt this query a bit, based on your requirements...