How to get any three rows of particular date in SQL Server - sql-server-2008

I am stucking in one sql query.
My table format is the below:
Acct# AdmitDate DOS ChargeAmount
12366 2011-12-07 00:00:00.000 2011-12-15 00:00:00.000 25.00
12366 2011-12-07 00:00:00.000 2011-12-16 00:00:00.000 30.00
12366 2011-12-07 00:00:00.000 2011-12-17 00:00:00.000 55.00
12366 2011-12-07 00:00:00.000 2011-12-18 00:00:00.000 48.00
12366 2011-12-07 00:00:00.000 2011-12-19 00:00:00.000 25.00
12366 2012-01-08 00:00:00.000 2012-01-08 00:00:00.000 58.00
12366 2012-01-08 00:00:00.000 2012-01-09 00:00:00.000 46.00
12366 2012-01-08 00:00:00.000 2012-01-10 00:00:00.000 90.00
12366 2012-01-08 00:00:00.000 2012-01-11 00:00:00.000 52.00
12366 2012-01-08 00:00:00.000 2012-01-12 00:00:00.000 95.00
12366 2012-01-08 00:00:00.000 2012-01-13 00:00:00.000 53.20
I want only top 3 DOS by one Admit Date and sum of their ChargeAmount. All the other DOS should be neglact. I have no idea how to do this. I want the below desired output.
Acct# AdmitDate ChargeAmount
12366 2011-12-07 00:00:00.000 128.00
12366 2012-01-08 00:00:00.000 200.00
only 2011-12-17 to 2011-12-19 for Admit Date 2011-12-07 need to be sum and do the same for other Admit date.
If you have any sql query please share with me.
Thanks in advance

Try:
SELECT TOP 3 Acct, AdmitDate, SUM(ChargeAmount)
FROM YourTable
GROUP BY Acct, AdmitDate
Edit
SELECT Acct, AdmitDate, SUM(ChargeAmount)
, RANK() OVER (PARTITION BY AdmitDate ORDER BY AdmitDate DESC)
FROM YourTable
GROUP BY Acct, AdmitDate

Select
Acct#,
AdmitDate,
sum(ChargeAmount) ChargeAmount
from
(Select
Acct#,
AdmitDate,
row_number() over(partition by AdmitDate order by DOS desc) RowNo,
ChargeAmount
from TableName
where Acct# = #AcctNumber
) as t
where (RowNo = 1 or RowNo = 2 or RowNo = 3)
group by Acct#, AdmitDate
I have found the query. This query is working fine for me. Thanks for your efforts.

Related

How to calculate most recent year out a table with older values in MySQL?

I'm having trouble querying the data to get only the orders the employees did in the last year, instead of all years.
This is the result for all years:
SELECT FirstName as 'Voornaam', Lastname as 'Familienaam', COUNT(Orders.OrderDate) as 'Behandelde Orders'
FROM Employees, Orders
WHERE ReportsTo IS NOT NULL
AND Employees.EmployeeID = Orders.EmployeeID
GROUP BY Orders.EmployeeID, FirstName, Lastname
ORDER BY Orders.EmployeeID
which gives
Voornaam Familienaam Behandelde Orders
Nancy----- Davolio ------123
Janet------ Leverling ----127
Margaret-- Peacock ----156
Steven ----Buchanan ---42
Michael ---Suyama ----- 67
Robert ----King --------- 72
Laura -----Callahan -----104
Anne ----- Dodsworth ---43
Now I want to do the same but only for the most recent year. Here you can see a bit of the table Orders. It contains older dates:
OrderID CustomerID EmployeeID OrderDate RequiredDate ShippedDate ShipVia Freight ShipName ShipAddress ShipCity ShipRegion ShipPostalCode ShipCountry
----------- ---------- ----------- ----------------------- ----------------------- ----------------------- ----------- --------------------- ---------------------------------------- ------------------------------------------------------------ --------------- --------------- -------------- ---------------
10248 VINET 5 1996-07-04 00:00:00.000 1996-08-01 00:00:00.000 1996-07-16 00:00:00.000 3 32,38 Vins et alcools Chevalier 59 rue de l'Abbaye Reims NULL 51100 France
10249 TOMSP 6 1996-07-05 00:00:00.000 1996-08-16 00:00:00.000 1996-07-10 00:00:00.000 1 11,61 Toms Spezialitäten Luisenstr. 48 Münster NULL 44087 Germany
10250 HANAR 4 1996-07-08 00:00:00.000 1996-08-05 00:00:00.000 1996-07-12 00:00:00.000 2 65,83 Hanari Carnes Rua do Paço, 67 Rio de Janeiro RJ 05454-876 Brazil
10251 VICTE 3 1996-07-08 00:00:00.000 1996-08-05 00:00:00.000 1996-07-15 00:00:00.000 1 41,34 Victuailles en stock 2, rue du Commerce Lyon NULL 69004 France
10252 SUPRD 4 1996-07-09 00:00:00.000 1996-08-06 00:00:00.000 1996-07-11 00:00:00.000 2 51,30 Suprêmes délices Boulevard Tirou, 255 Charleroi NULL B-6000 Belgium
10253 HANAR 3 1996-07-10 00:00:00.000 1996-07-24 00:00:00.000 1996-07-16 00:00:00.000 2 58,17 Hanari Carnes Rua do Paço, 67 Rio de Janeiro RJ 05454-876 Brazil
10254 CHOPS 5 1996-07-11 00:00:00.000 1996-08-08 00:00:00.000 1996-07-23 00:00:00.000 2 22,98 Chop-suey Chinese Hauptstr. 31 Bern NULL 3012 Switzerland
10255 RICSU 9 1996-07-12 00:00:00.000 1996-08-09 00:00:00.000 1996-07-15 00:00:00.000 3 148,33 Richter Supermarkt Starenweg 5 Genève NULL 1204 Switzerland
10256 WELLI 3 1996-07-15 00:00:00.000 1996-08-12 00:00:00.000 1996-07-17 00:00:00.000 2 13,97 Wellington Importadora Rua do Mercado, 12 Resende SP 08737-363 Brazil
10257 HILAA 4 1996-07-16 00:00:00.000 1996-08-13 00:00:00.000 1996-07-22 00:00:00.000 3 81,91 HILARION-Abastos Carrera 22 con Ave. Carlos Soublette #8-35 San Cristóbal Táchira 5022 Venezuela
10258 ERNSH 1 1996-07-17 00:00:00.000 1996-08-14 00:00:00.000 1996-07-23 00:00:00.000 1 140,51 Ernst Handel Kirchgasse 6 Graz NULL 8010 Austria
10259 CENTC 4 1996-07-18 00:00:00.000 1996-08-15 00:00:00.000 1996-07-25 00:00:00.000 3 3,25 Centro comercial Moctezuma Sierras de Granada 9993 México D.F. NULL 05022 Mexico
10260 OTTIK 4 1996-07-19 00:00:00.000 1996-08-16 00:00:00.000 1996-07-29 00:00:00.000 1 55,09 Ottilies Käseladen Mehrheimerstr. 369 Köln NULL 50739 Germany
I tried:
SELECT FirstName as 'Voornaam', Lastname as 'Familienaam', COUNT(Orders.OrderDate) as 'Behandelde Orders'
FROM Employees, Orders
WHERE ReportsTo IS NOT NULL
AND Employees.EmployeeID = Orders.EmployeeID
GROUP BY Orders.EmployeeID, FirstName, Lastname
ORDER BY Orders.EmployeeID
HAVING Orders.OrderDate = Max(Year(Orders.OrderDate))
SELECT FirstName as 'Voornaam', Lastname as 'Familienaam', COUNT(Orders.OrderDate) as 'Behandelde Orders'
FROM Employees, Orders
WHERE ReportsTo IS NOT NULL
AND Orders.OrderDate = Max(Year(Orders.OrderDate)))
AND Employees.EmployeeID = Orders.EmployeeID
GROUP BY Orders.EmployeeID, FirstName, Lastname
ORDER BY Orders.EmployeeID
SELECT FirstName as 'Voornaam', Lastname as 'Familienaam', COUNT(Orders.EmployeeID) as 'Behandelde Orders'
FROM Employees, Orders
WHERE ReportsTo IS NOT NULL
AND Orders.OrderDate = Max(year(Orders.OrderDate))
AND Employees.EmployeeID = Orders.EmployeeID
GROUP BY Orders.EmployeeID, FirstName, Lastname
ORDER BY Orders.EmployeeID
and a few other variations.
First, never use commas in the FROM clause. Always use correct, explicit JOIN syntax.
The following version assumes that you want the most recent calendar year per person:
SELECT FirstName as Voornaam, Lastname as Familienaam,
COUNT(o.OrderDate) as BehandeldeOrders
FROM Employees e JOIN
Orders o
ON e.EmployeeID = o.EmployeeID
WHERE ReportsTo IS NOT NULL AND
YEAR(o.OrderDate) = (SELECT YEAR(MAX(o2.OrderDate))
FROM Orders o2
WHERE o2.EmployeeId = o.EmployeeId
)
GROUP BY o.EmployeeID, FirstName, Lastname
ORDER BY o.EmployeeID;
You can remove the correlated clause (the WHERE in the subquery) if you want the most recent year overall.

Calculation to be made while updating a field

Origin Dest Date Amount 50% Due
92509 0021 2013-07-30 00:00:00.000 5.37 0.00
92509 0021 2013-07-30 00:00:00.000 5.37 0.00
92509 0021 2013-07-30 00:00:00.000 5.37 0.00
92509 0021 2013-07-31 00:00:00.000 5.37 2.69
92509 0021 2013-07-31 00:00:00.000 5.37 2.69
92509 0021 2013-07-31 00:00:00.000 5.37 2.69
92509 0021 2013-08-01 00:00:00.000 5.37 2.69
92509 0021 2013-08-01 00:00:00.000 5.37 2.69
42101 0029 2013-03-06 00:00:00.000 6.06 0.00
42101 0029 2013-03-06 00:00:00.000 6.06 0.00
42101 0029 2013-03-07 00:00:00.000 6.06 3.03
42101 0029 2013-03-07 00:00:00.000 6.06 3.03
42101 0030 2013-03-06 00:00:00.000 6.06 0.00
42101 0030 2013-03-06 00:00:00.000 6.06 0.00
42101 0030 2013-03-07 00:00:00.000 6.06 3.03
42101 0030 2013-03-07 00:00:00.000 6.06 3.03
So I have a table something similar to what i shown above. Right now, the 50% Due field is empty. I need to fill that field with values as shown above.
The 50% due field should populate values that are half of what is present in the Amount field. But, it should fill zero for the initial date (2013-07-30 00:00:00.000) and for the consecutive days it should fill half of what is present in the Amount field.
I have a lot of rows like these that needs to get updated. Also there are rows with different Origin and Destination.
I am dealing with some freight parcels. The data describes the parcels that were sent to the same destination from same origin on consecutive days. The parcels that were sent on consecutive days could have been sent together on the initial date itself. So I am trying to generate a claim for those parcels that were sent on consecutive days to the same destination from the same origin. And the 50% Due would be the claim!
I am fairly new to SQL! This seems to be very complicated for me. Please help.
If you want to update all origin/dest combinations that had an entry on the prior day then you can do this:
update t
set [50% due]=coalesce(cast(p.amount/2.0 as smallmoney),0.00)
from [table] t
left join [table] p
on t.origin=p.origin and t.dest=p.dest
and dateadd(D,-1,cast(t.[date] as date))=cast(p.[date] as date)
or use a cte and LAG in SQL 2012 and later versions:
;with previous as
(
select origin,dest,[date]
,LAG(cast([date] as date),1,cast([date] as date)) OVER (PARTITION BY origin,dest ORDER BY cast([date] as date)) as previous
from (select distinct origin, dest, [date]
from [table]) a
)
update t
set [50% Due]=case when dateadd(D,-1,cast(t.[date] as date))<>cte.previous then 0.00 else cast(t.[amount]/2.0 as smallmoney) end
from [table] t
join previous cte
on cte.origin=t.origin and cte.dest=t.dest and cte.[date]=t.[date]
If you want to update all your records based on the earliest day that the origin/dest combination occurred, then this will work in SQL Server:
;with earliest as
(
select origin,dest,min(cast([date] as date)) earliest
from [table]
group by origin,dest
)
update t
set [50% Due]=case when cast(t.[date] as date)=cte.earliest then 0.00 else cast(t.[amount]/2.0 as smallmoney) end
from [table] t
join earliest cte
on cte.origin=t.origin and cte.dest=t.dest
If you want to update all your records only based on the earliest day in the table and you don't care about the orgin/dest combination then you don't need the cte to group the earliest dates and you can simply do the compare in the update.
UPDATE t
set [50% Due]=case when cast(t.[date] as date)=(select min(cast(t.date as date))) then 0.00 else cast(t.[amount]/2.0 as smallmoney) end

Date conversion using SSIS

I am trying to load excel data into a table using SSIS.
In my excel, there is one column 'TRANSACTION DATE'.
TRANSACTION_DATE IN EXCEL TRANSACTION_DATE IN TABLE
01/12/2014 2014-01-12 00:00:00.000
01/12/2014 2014-01-12 00:00:00.000
02/12/2014 2014-02-12 00:00:00.000
05/12/2014 2014-05-12 00:00:00.000
05/12/2014 2014-05-12 00:00:00.000
13/12/2014 2014-12-13 00:00:00.000
16/12/2014 2014-12-16 00:00:00.000
16/12/2014 2014-12-16 00:00:00.000
19/12/2014 2014-12-19 00:00:00.000
20/12/2014 2014-12-20 00:00:00.000
22/12/2014 2014-12-22 00:00:00.000
26/12/2014 2014-12-26 00:00:00.000
29/12/2014 2014-12-29 00:00:00.000
31/12/2014 2014-12-31 00:00:00.000
31/12/2014 2014-12-31 00:00:00.000
Problem:
If you observe first 5 rows in the table values, the syntax is quite different with other values of the table.it should be (2014-12-01,2014-12-02 etc..). Because of this issue, if I fire a query to sum the values of of another column where DATEPART(MM,TRANSACTION_DATE)=12, The top 5 values are getting excluded.
Table Structure :
TRANSACTION_DATE DATETIME
SSIS DATA CONVERSION :
TRANSACTION_DATE DT_DBDATE
What's happening is the first 5 records are being parsed in the American format (MM/DD/YYYY), and the rest of the records are being parsed as DD/MM/YYYY.
Check the datetime format of the cells in Excel to make sure the Locale setting is consistent for all the dates.

Double ORDER BY sort with UNION statement

(
SELECT *
FROM (
SELECT d
FROM myTable
WHERE id = "4h"
AND d < "2011-12-08 12:00:00"
ORDER BY d DESC
LIMIT 10
)tmp
ORDER BY d ASC
)
UNION (
SELECT d
FROM myTable
WHERE id = "4h"
AND d >= "2011-12-08 12:00:00"
ORDER BY d ASC
LIMIT 10
)
I'm trying to get the 10 results before and after a particular ID by using two SELECT statements and a UNION. The first SELECT uses ORDER BY DESC to get the 10 preceding and then I attempt to envelope that in a second ORDER BY ASC to get all the results in ASC order but for some reason it does not work.
Here is what I get currently for a result:
d
2011-12-08 08:00:00
2011-12-08 04:00:00
2011-12-08 00:00:00
2011-12-07 20:00:00
2011-12-07 16:00:00
2011-12-07 12:00:00
2011-12-07 08:00:00
2011-12-07 04:00:00
2011-12-07 00:00:00
2011-12-06 20:00:00 <- These top 10 results should ASC!
2011-12-08 12:00:00
2011-12-08 16:00:00
2011-12-08 20:00:00
2011-12-09 00:00:00
2011-12-09 04:00:00
2011-12-09 08:00:00
2011-12-09 12:00:00
2011-12-09 16:00:00
2011-12-09 20:00:00
2011-12-11 20:00:00
And here is what I want:
d
2011-12-06 20:00:00
2011-12-07 00:00:00
2011-12-07 04:00:00
2011-12-07 08:00:00
2011-12-07 12:00:00
2011-12-07 16:00:00
2011-12-07 20:00:00
2011-12-08 00:00:00
2011-12-08 04:00:00
2011-12-08 08:00:00
2011-12-08 12:00:00
2011-12-08 16:00:00
2011-12-08 20:00:00
2011-12-09 00:00:00
2011-12-09 04:00:00
2011-12-09 08:00:00
2011-12-09 12:00:00
2011-12-09 16:00:00
2011-12-09 20:00:00
2011-12-11 20:00:00
(
SELECT d
FROM myTable
WHERE id = '4h' AND d < '2011-12-08 12:00:00'
ORDER BY d DESC
LIMIT 10
) UNION ALL (
SELECT d
FROM myTable
WHERE id = '4h' AND d >= '2011-12-08 12:00:00'
ORDER BY d ASC
LIMIT 10
)
ORDER BY d ASC

JOIN unrelated tables by t1.date (between t2.startdate and t2.enddate)

A SQL question, probably not the most difficult.
I'm making a view from a bunch of related table join on ID's -> easy. Now there is one table that hasn't got a key relationship with all the others. (BatchDates)
`ALTER VIEW [ECSUB].[FCT_Ext_Collection]
AS
SELECT sh.id AS idSubmissionHistory, dh.id, dd.id AS Description, sch.id AS idScoringHistory, sh.CreationDate, sh.UpdateDate, bd.id AS BatchDateID
FROM ECSUB.SubmissionHistory AS sh INNER JOIN EC.DocumentHistory AS dh ON sh.id = dh.idSubmissionHistory
LEFT OUTER JOIN ECSM.ScoringHistory AS sch ON sh.idScoringHistory = sch.id
LEFT OUTER JOIN EC.DocumentDescriptions AS dd ON dd.id = dh.Description
LEFT OUTER JOIN ECSUB.AddressBilling AS ab ON sh.id = ab.id
LEFT OUTER JOIN ECSUB.AddressPremise AS ap ON sh.id = ap.id
CROSS JOIN EC.BatchDates AS bd --ON sh.documentdate between .......
GO`
Well, my main table 'documentHistory' contains a document date, I have to define in which batch this falls.
Each batch has an ID and startdate. A batch is always one month long.
This will make it much more easy to understand, the data from the BatchDates table:
id month startdate
1 2010-12-01 00:00:00.000 2010-12-01 00:00:00.000
1 2011-01-01 00:00:00.000 2010-12-01 00:00:00.000
1 2011-02-01 00:00:00.000 2010-12-01 00:00:00.000
2 2011-03-01 00:00:00.000 2011-03-01 00:00:00.000
2 2011-04-01 00:00:00.000 2011-03-01 00:00:00.000
2 2011-05-01 00:00:00.000 2011-03-01 00:00:00.000
3 2011-06-01 00:00:00.000 2011-06-01 00:00:00.000
3 2011-07-01 00:00:00.000 2011-06-01 00:00:00.000
3 2011-08-01 00:00:00.000 2011-06-01 00:00:00.000
4 2011-09-01 00:00:00.000 2011-09-01 00:00:00.000
4 2011-10-01 00:00:00.000 2011-09-01 00:00:00.000
4 2011-11-01 00:00:00.000 2011-09-01 00:00:00.000
5 2011-12-01 00:00:00.000 2011-12-01 00:00:00.000
5 2012-01-01 00:00:00.000 2011-12-01 00:00:00.000
5 2012-02-01 00:00:00.000 2011-12-01 00:00:00.000
6 2012-03-01 00:00:00.000 2012-03-01 00:00:00.000
6 2012-04-01 00:00:00.000 2012-03-01 00:00:00.000
6 2012-05-01 00:00:00.000 2012-03-01 00:00:00.000
7 2012-06-01 00:00:00.000 2012-06-01 00:00:00.000
7 2012-07-01 00:00:00.000 2012-06-01 00:00:00.000
7 2012-08-01 00:00:00.000 2012-06-01 00:00:00.000
8 2012-09-01 00:00:00.000 2012-09-01 00:00:00.000
8 2012-10-01 00:00:00.000 2012-09-01 00:00:00.000
8 2012-11-01 00:00:00.000 2012-09-01 00:00:00.000
9 2012-12-01 00:00:00.000 2012-12-01 00:00:00.000
9 2013-01-01 00:00:00.000 2012-12-01 00:00:00.000
9 2013-02-01 00:00:00.000 2012-12-01 00:00:00.000
10 2013-03-01 00:00:00.000 2013-03-01 00:00:00.000
10 2013-04-01 00:00:00.000 2013-03-01 00:00:00.000
10 2013-05-01 00:00:00.000 2013-03-01 00:00:00.000
etc...........
So I need to fetch the batchID based on the documentdate, therefore we use the currentMonth of the column startdate.
Thus: ...JOIN BatchDates where documentDate is in startDate.month (there is no between here)
I don't even know if I need a join, cross join, union, etc...
Thanks in advance!
L
join BatchDates
on datepart(yyyy,[document date]) = datepart(yyyy,[startDate])
and datepart(mm,[document date]) = datepart(mm,[startDate])