I have a small issue with a stored procedure in SQL Server 2005.
RepInfoID(primary), Date, RepID are the columns in RepInfo
1. 25660, 02/03/2012, 100
2. 25661, 02/03/2012, 100
3. 25662, 02/03/2012, 101
and
RepCID(primary), RepInfoID, Amount are the columns in RepCollection
1. 4343, 25660, 200(money)
2. 4344, 25661, 600
Desired results is:
100(RepID) , 02/03/2012, 800(money)
There can be more than row with the same date.
When a date is selected, foreach RepID on the selected date, I want the sum of Amount on that particular day. I hope I am clear.
Thank you for your help..
CREATE PROCEDURE [dbo].[PracticewithAmount]
(#Date datetime)
AS
BEGIN
Select *
from RepInfo
left outer join RepCollection on RepInfo.RepInfoID = RepCollection.RepInfoID
where RepInfo.Date = #Date
and distinct(RepID)
END
Your question isn't entirely clear, but here's what I think you're saying:
SELECT
--i.RepInfoID(primary),
i.Date,
i.RepID,
--c.RepCID(primary),
--c.RepInfoID,
sum(c.Amount) as Amount
FROM
RepInfo i
LEFT JOIN RepCollection c
ON i.RepInfoID = c.RepInfoID
WHERE
i.Date = #Date
GROUP BY
i.Date,
i.RepID
Related
I´m having issues with the following query. I have two tables; Table Orderheader and table Bought. The first query I execute gives me, for example, two dates. Based on these two dates, I need to find Production data AND, based on the production data, I need to find the Bought data, and combine those data together. Lets say I do the following:
Select Lotdate From Orderheader where orhsysid = 1
This results in two rows: '2019-02-05' and '2019-02-04'. Now I need to do two things: I need two run two queries using this result set. The first one is easy; use the dates returned and get a sum of column A like this:
Select date, SUM(Amount) from Orderheader where date = Sales.date() [use the two dates here]
The second one is slighty more complicated, I need to find the last day where something has been bought based on the two dates. Production is everyday so Productiondate=Sales.date()-1. But Bought is derived from Productionday and is not everyday so for every Productionday it needs to find the last Boughtday. So I can't say where date = Orderheader.date. I need to do something like:
Select date, SUM(Amount)
FROM Bought
WHERE date = (
SELECT top 1 date
FROM Bought
WHERE date < Orderheader.date)
But twice, for both the dates I got.
This needs to result in 1 table giving me:
Bought.date, Bought.SUM(AMOUNT), Orderheader.date, Orderheader.SUM(AMOUNT)
All based on the, possible multiple, Lotdate(s) I got from the first query from Sales table.
I've been struggling with this for a moment now, using joins and nested queries but I can't seem to figure it out!
Example sample:
SELECT CONVERT(date,ORF.orfDate) as Productiedatum, SUM(orlQuantityRegistered) as 'Aantal'
FROM OrderHeader ORH
LEFT JOIN OrderFrame ORF ON ORH.orhFrameSysID = ORF.orfSysID
LEFT JOIN OrderLine ORL ON ORL.orhSysID = ORH.orhSysID
LEFT JOIN Item ON Item.itmSysID = ORL.orlitmSysID
where CONVERT(date,ORF.orfDate) IN
(
SELECT DISTINCT(CONVERT(date, Lot.lotproductiondate)) as Productiedatum
FROM OrderHeader ORH
LEFT JOIN Registration reg ON reg.regorhSysID = ORH.orhSysID
LEFT JOIN StockRegistration stcreg ON stcreg.stcregRegistrationSysID = reg.regSysID
LEFT JOIN Lot ON Lot.lotSysID = stcregSrclotSysID
WHERE ORH.orhSysID = 514955
AND regRevokeRegSysID IS NULL
AND stcregSrcitmSysID = 5103
)
AND ORL.orlitmSysID = 5103
AND orldirSysID = 2
AND NOT orlQuantityRegistered IS NULL
GROUP BY Orf.orfDate
Sample output:
Productiedatum Aantal
2019-02-05 20
2019-02-06 20
Here I used a nested subquery to get the results from 'Production' (orderheader) because I just can use date = date. I'm struggling with the Sales part where I need to find the last date(s) and use those dates in the Sales table to get the sum of that date.
Expected output:
Productiedatum Aantal Boughtdate Aantal
2019-02-04 20 2019-02-01 55
2019-02-05 20 2019-02-04 60
Try this.
IF OBJECT_ID('tempdb..#Production') IS NOT NULL DROP TABLE #Production
IF OBJECT_ID('tempdb..#Bought') IS NOT NULL DROP TABLE #Bought
CREATE table #Production(R_NO int,ProductionDate datetime,ProductionAmount float)
CREATE table #Bought(R_NO int,Boughtdate datetime,Boughtamount float)
insert into #Production(ProductionDate,ProductionAmount,R_NO)
select p.date ProductionDate,sum(Amount) ProductionAmount,row_number()over (order by p.date) R_NO
from Production P
join Sales s on p.date=S.date-1
where orhsysid=1
group by p.date
declare #loop int,#ProdDate datetime
select #loop =max(R_NO) from #Production
while (1<=#loop)
begin
select #ProdDate=ProductionDate from #Production where r_no=#loop
insert into #Bought(Boughtdate,Boughtamount,R_NO)
select Date,Sum(Amount),#loop R_NO from Bought where date=(
select max(date) from bought B
where B.Date<#ProdDate)
group by Date
set #loop=#loop-1
end
select ProductionDate,ProductionAmount,Boughtdate,Boughtamount from #Bought B
join #Production p on B.R_NO=P.R_NO
Hie I want to extract data from 3 tables and their rows as follows:
**RentalAgreement – CustID,AgreementID(PK) and AgreementDate
**Movie Rented – AgreementID(PK), RentalAmount and PercentReductionApplied,MovieID(FK)
**Movie – MovieID(PK), Name, Released
Where i need to display the data from last 30 days based on table and not the current data.
How can i go about achieving this?
My try:
SELECT TRIM(CustID),AgreementDate , RentalAmount
,PercentReductionApplied , MovieID , Name , Released
FROM RentalAgreement, MovieRented, Movie
WHERE RentalAgreement.AgreementID = MovieRented.AgreementID
AND Movie.MovieID = MovieRented.MovieID
AND AgreementDate BETWEEN MAX(AgreementDate) AND MAX(AgreementDate)-30;
The problem is with MAX(agreementdate). That is an aggregate function - you can only access it in the last stage of a query (in the SELECT clause), after the WHERE clause has been processed. Which means you need a different query to compute the MAX first - and use it as a subquery in your overall (outer) query.
It is also best to use modern, SQL standard join syntax. Putting both of these together:
SELECT TRIM(CustID),AgreementDate , RentalAmount
,PercentReductionApplied , MovieID , Name , Released
FROM RentalAgreement
join MovieRented on RentalAgreement.AgreementID = MovieRented.AgreementID
join Movie on Movie.MovieID = MovieRented.MovieID
cross join (select max(agreementdate) as max_date from rentalagreement) m
where AgreementDate BETWEEN m.max_date AND m.max_date - 30;
Why do you need to TRIM(custID)? That's quite unusual. Also odd that AgreementID is PRIMARY key in MovieRented. But these are not the reasons your query didn't work.
DECLARE #StartDate DATETIME,#EndDate DATETIME
SELECT #StartDate = MAX(AgreementDate) FROM RentalAgreement
SET #EndDate = DATEADD(DAY,-30,#StartDate)
SELECT TRIM(CustID),AgreementDate , RentalAmount
,PercentReductionApplied , MovieID , Name , Released
FROM RentalAgreement, MovieRented, Movie
WHERE RentalAgreement.AgreementID = MovieRented.AgreementID
AND Movie.MovieID = MovieRented.MovieID
AND AgreementDate BETWEEN #StartDate AND #EndDate
I have what seems to be a common business request but I can't find no clear solution. I have a daily report (amongst many) that gets generated based on failed criteria and gets saved to a table. Each report has a type id tied to it to signify which report it is, and there is an import event id that signifies the day the imports came in (a date column is added for extra clarification). I've added a sqlfiddle to see the basic schema of the table (renamed for privacy issues).
http://www.sqlfiddle.com/#!3/81945/8
All reports currently generated are working fine, so nothing needs to be modified on the table. However, for one report (type 11), not only I need pull the invoices that showed up today, I also need to add one column that totals the amount of consecutive days from date of run for that invoice (including current day). The result should look like the following, based on the schema provided:
INVOICE MESSAGE EVENT_DATE CONSECUTIVE_DAYS_ON_REPORT
12345 Yes July, 30 2013 6
54355 Yes July, 30 2013 2
644644 Yes July, 30 2013 4
I only need the latest consecutive days, not any other set that may show up. I've tried to run self joins to no avail, and my last attempt is also listed as part of the sqlfiddle file, to no avail. Any suggestions or ideas? I'm quite stuck at the moment.
FYI: I am working in SQL Server 2000! I have seen a lot of neat tricks that have come out in 2005 and 2008, but I can't access them.
Your help is greatly appreciated!
Something like this? http://www.sqlfiddle.com/#!3/81945/14
SELECT
[final].*,
[last].total_rows
FROM
tblEventInfo AS [final]
INNER JOIN
(
SELECT
[first_of_last].type_id,
[first_of_last].invoice,
MAX([all_of_last].event_date) AS event_date,
COUNT(*) AS total_rows
FROM
(
SELECT
[current].type_id,
[current].invoice,
MAX([current].event_date) AS event_date
FROM
tblEventInfo AS [current]
LEFT JOIN
tblEventInfo AS [previous]
ON [previous].type_id = [current].type_id
AND [previous].invoice = [current].invoice
AND [previous].event_date = [current].event_date-1
WHERE
[current].type_id = 11
AND [previous].type_id IS NULL
GROUP BY
[current].type_id,
[current].invoice
)
AS [first_of_last]
INNER JOIN
tblEventInfo AS [all_of_last]
ON [all_of_last].type_id = [first_of_last].type_id
AND [all_of_last].invoice = [first_of_last].invoice
AND [all_of_last].event_date >= [first_of_last].event_date
GROUP BY
[first_of_last].type_id,
[first_of_last].invoice
)
AS [last]
ON [last].type_id = [final].type_id
AND [last].invoice = [final].invoice
AND [last].event_date = [final].event_date
The inner most query looks up the starting record of the last block of consecutive records.
Then that joins on to all the records in that block of consecutive records, giving the final date and the count of rows (consecutive days).
Then that joins on to the row for the last day to get the message, etc.
Make sure that in reality you have an index on (type_id, invoice, event_date).
You have multiple problems. Tackle them separately and build up.
Problems:
1) Identifying consecutive ranges: subtract the row_number from the range column and group by the result
2) No ROW_NUMBER() functions in SQL 2000: Fake it with a correlated subquery.
3) You actually want DENSE_RANK() instead of ROW_NUMBER: Make a list of unique dates first.
Solutions:
3)
SELECT MAX(id) AS id,invoice,event_date FROM tblEventInfo GROUP BY invoice,event_date
2)
SELECT t2.invoice,t2.event_date,t2.id,
DATEDIFF(day,(SELECT COUNT(DISTINCT event_date) FROM (SELECT MAX(id) AS id,invoice,event_date FROM tblEventInfo GROUP BY invoice,event_date) t1 WHERE t2.invoice = t1.invoice AND t2.event_date > t1.event_date),t2.event_date) grp
FROM (SELECT MAX(id) AS id,invoice,event_date FROM tblEventInfo GROUP BY invoice,event_date) t2
ORDER BY invoice,grp,event_date
1)
SELECT
t3.invoice AS INVOICE,
MAX(t3.event_date) AS EVENT_DATE,
COUNT(t3.event_date) AS CONSECUTIVE_DAYS_ON_REPORT
FROM (
SELECT t2.invoice,t2.event_date,t2.id,
DATEDIFF(day,(SELECT COUNT(DISTINCT event_date) FROM (SELECT MAX(id) AS id,invoice,event_date FROM tblEventInfo GROUP BY invoice,event_date) t1 WHERE t2.invoice = t1.invoice AND t2.id > t1.id),t2.event_date) grp
FROM (SELECT MAX(id) AS id,invoice,event_date FROM tblEventInfo GROUP BY invoice,event_date) t2
) t3
GROUP BY t3.invoice,t3.grp
The rest of your question is a little ambiguous. If two ranges are of equal length, do you want both or just the most recent? Should the output MESSAGE be 'Yes' if any message = 'Yes' or only if the most recent message = 'Yes'?
This should give you enough of a breadcrumb though
I had a similar requirement not long ago getting a "Top 5" ranking with a consecutive number of periods in Top 5. The only solution I found was to do it in a cursor. The cursor has a date = #daybefore and inside the cursor if your data does not match quit the loop, otherwise set #daybefore = datediff(dd, -1, #daybefore).
Let me know if you want an example. There just seem to be a large number of enthusiasts, who hit downvote when they see the word "cursor" even if they don't have a better solution...
Here, try a scalar function like this:
CREATE FUNCTION ConsequtiveDays
(
#invoice bigint, #date datetime
)
RETURNS int
AS
BEGIN
DECLARE #ct int = 0, #Count_Date datetime, #Last_Date datetime
SELECT #Last_Date = #date
DECLARE counter CURSOR LOCAL FAST_FORWARD
FOR
SELECT event_date FROM tblEventInfo
WHERE invoice = #invoice
ORDER BY event_date DESC
FETCH NEXT FROM counter
INTO #Count_Date
WHILE ##FETCH_STATUS = 0 AND DATEDIFF(dd,#Last_Date,#Count_Date) < 2
BEGIN
#ct = #ct + 1
END
CLOSE counter
DEALLOCATE counter
RETURN #ct
END
GO
In an Access database there are two tables.
Table one containing Articles and table two contains Prices.
So Articles is the description of all articles and the prices
table just contains an article number, a date date and a price.
If a prices changes, there will be added a new row to prices.
The prices have a date from which on that price shall be used.
Now I want to get the prices that were valid on 01. Oct 2012.
I used my query on current prices and added and prsdat<#02/10/2012#
to the subselect in the query.
Here is what I already have:
SELECT
Articles.ARTNR,
Articles.TXT,
Articles.ACTIVE,
Prices.PRICE,
Prices.PRSGR,
Prices.PRSDAT
FROM
Articles INNER JOIN Prices ON Articles.ARTNR = Prices.ARTNR
WHERE
(((Articles.ACTIVE)="Y") AND
((Prices.PRSGR)=0) AND
((Prices.PRSDAT)=
(SELECT
max(prsdat)
FROM
Prices as art
WHERE
art.artnr = Prices.artnr and prsdat<#02/10/2012#)))
ORDER BY
Articles.ARTNR;
Now the select returns articles that I did not see with this select
I used before, having just added and prsdat<#01/10/2012#.
The result is now 430 articles, before I just had about 260.
The prices returned are older, but I'm not sure about the date format.
In the table I see DD.MM.YYYY, and in the query i shall use MM/DD/YYYY or DD/MM/YYYY?
What is the correct form of this select?
SELECT
a.ARTNR
, a.TXT
, a.ACTIVE -- dubious, since it is constant
, p.PRICE
, p.PRSGR -- dubious, since it is constant
, p.PRSDAT
FROM Articles a
INNER JOIN Prices p ON a.ARTNR = p.ARTNR
WHERE a.ACTIVE = 'Y'
AND p.PRSGR = 0
AND p.prsdat < #02/10/2012#
AND NOT EXISTS (
SELECT *
FROM Prices nx
WHERE nx.ARTNR = p.ARTNR
AND nx.PRSGR = 0
AND nx.prsdat < #02/10/2012#
AND nx.prsdat > p.prsdat
)
ORDER BY
Articles.ARTNR
;
I have three tables Books, Debit and Client.
Books (Id, Title, ...)
Debit (BooksID, ClientId, BorrowingDate,....)
Client (Id, Name, ...)
I need SQL query that will return
a book that is most times rented out, between two dates.
Dates will be passed as parameters to query.
How about this?
SELECT * FROM Books INNER JOIN Debit ON Books.Id = Debit.BooksID WHERE BorrowingDate >= #StartDate AND BorrowingDate <= #EndDate
If you edit in an example of what you would like the output to look like I can redefine the above query to help you get what you want.
And for the record, Adrian is right; it is generally better to make an attempt yourself and come to us with a problem, rather than asking SO to solve the problem for you. But hopefully what I have here will get you started. Welcome to SO! :)
Edit
It also just occurred to me that you might be looking for the book which was rented out most number of times between your two dates... If so, try this:
SELECT TOP 1 Books.* FROM (
SELECT COUNT(*) AS DebitCount, BooksID FROM Debit WHERE BorrowingDate >= #StartDate AND BorrowingDate <= #EndDate GROUP BY BooksID
) Debits INNER JOIN Books ON Books.ID = Debits.BooksID
ORDER BY DebitCount DESC
Hope that helps!
The query...
SELECT TOP 1 *
FROM (
SELECT BooksID, COUNT(*) AS C
FROM Debit
WHERE BorrowingDate BETWEEN #min_date and #max_date
GROUP BY BooksID
)
ORDER BY C DESC
...will yield one row containing the BooksID and number of rents of the book that has been rented most times between #min_date and #max_date.
You can later easily JOIN with Books if you need more than just BooksID.