I need the output from this.. i know this is wrong it is just an example
SELECT
customer_name,
((Qty * 0.5), *
(CASE WHEN (DATEDIFF(month, Appointment_Date,getdate())) < 12 )'Incentive'
FROM t1,t2
WHERE t1.customer_code = t2.customer_code
I think you are looking for this:
select customer_name,((Qty * 0.5) *
(case when (datediff (month, Appointment_Date,getdate()) < 12 ) then
datediff (month, Appointment_Date,getdate()) else 1 end ) )'Incentive'
from t1,t2
where t1.customer_code = t2.customer_code
As far as I understand from your comments (please read introductory notes on how to post on S.O.), maybe you can use a query like this.
I changed your original query using JOIN clause too.
SELECT
customer_name,
Qty * 0.5 *DATEDIFF(month, Appointment_Date,getdate()) AS INCENTIVE
FROM t1
INNER JOIN t2 ON t1.customer_code = t2.customer_code
WHERE DATEDIFF(month, Appointment_Date,getdate()) < 12
Related
i have an example data :
I need to get the count of SNs for the next 5 seconds where the SNs are of the same type and the same selection
I tried using join but didn't quite get to the point. Is there a way to get this.
select *
from TestData t1
cross apply
(
select
count(*) [Count],
isnull(string_agg(t2.SN, ','), '-') [Related SN]
from TestData t2
where
t2.SN <> t1.SN
and t2.Type = t1.Type
and t2.Selection = t1.Selection
and t2.DT >= t1.DT
and datediff(second, t1.DT, t2.DT) < 5
) RelatedSN;
I am trying to update (using Inner joins for three tables) item stats STAT for table IM_ITEM by highlighting items that sold less than 12 as "D" (Discontinue).
The 2nd table PS_TKT_HIST_LIN has the Quantity sold column QTY_SOLD for each item on each day and the date column BUS_DAT.
I also need a third table IM_INV to filter the data, I need to say the last received date LST_RECV_DAT for these items is earlier than "2019-01-01" and last sales date LST_SAL_DAT is after "2019-01-01". I used the following code
UPDATE M
SET M.STAT = 'D'
FROM
dbo.IM_ITEM AS M
INNER JOIN
IM_INV AS N
ON
M.ITEM_NO = N.ITEM_NO
INNER JOIN
dbo.PS_TKT_HIST_LIN S`
ON
M.ITEM_NO = S.ITEM_NO
WHERE
CONVERT(DATETIME, FLOOR(CONVERT(FLOAT, N.LST_RECV_DAT))) <= '2019-01-01'
AND CONVERT(DATETIME, FLOOR(CONVERT(FLOAT, N.LST_SAL_DAT))) >= '2019-01-01'
AND M.STAT = 'A'
AND SUM(case when DATEPART(YYYY, (BUS_DAT)) = DATEPART(YYYY, DATEADD(YYYY, -1, getdate()))
AND DATEPART(yyyy, (BUS_DAT)) = DATEPART(yyyy, DATEADD(YYYY, -1, getdate()))
then qty_sold else 0)<12
It comes with an error
Any advise please
You should use HAVING clause instead of Sum in where.
You can use CTE to achieve the value, then update accordingly.
;with cte as(
select ITEM_NO, ..
from ..
group by ITEM_NO
having .. < 12
)
update M
set SET M.STAT = 'D'
from dbo.IM_ITEM AS M
inner join cte on M.ITEM_NO = cte.ITEM_NO
You can't use an aggregate function in where clause unless defined under subquery.
We have a table that stores a list of all the quotes we have sent out.
Anytime a customer revises the quotes, the system automatically appends a -1 or -2 based on last used number.
As an example
Original Quote Number : 24545
Customer asked for a revision, the quote number is now 24545-1, after sending the quote, we now have a revision again and the Quote is 24545-2 and so on.
I want to run a SQL query that will show them their Top 20 Quotes and incase of revisions, it should show the latest revisions.
Can you please help me?
I have already written a Query that would bring me top 20 quotes for the last 10 days.
SELECT Top 20
EstimateNumber,CustName,JobDescription,TotalSellPrice,EstimateStatus,EstimateDate,CommissionTableA
FROM [Enterprise32].[dbo].[tablename1]
where EstimateDate BETWEEN DATEADD(Day, -10, getdate()) AND GETDATE() AND SalesRepCode = $id And TotalSellPrice > '5000' AND EstimateStatus = 'P'
Order By TotalSellPrice DESC
This makes some assumptions, but I think this might work. If not, sample data and expected result will be invaluable:
USE Enterprise32;
GO
WITH CTE AS(
SELECT V.EstimateNumber,
V.RevisionNumber,
TN1.CustName,
TN1.JobDescription,
TN1.TotalSellPrice,
TN1.EstimateStatus,
TN1.EstimateDate,
TN1.CommissionTableA,
ROW_NUMBER() OVER (PARTITION BY V.EstimateNumber ORDER BY V.RevisionNumber DESC) AS RN
FROM dbo.TableName1 TN1
CROSS APPLY (VALUES(NULLIF(CHARINDEX('-',TN1.EstimateNumber),0)))CI(I)
CROSS APPLY (VALUES(TRY_CONVERT(int,LEFT(TN1.EstimateNumber,ISNULL(CI.I,LEN(TN1.EstimateNumber))-1)),ISNULL(TRY_CONVERT(int,STUFF(TN1.EstimateNumber,1,CI.I,'')),0)))V(EstimateNumber,RevisionNumber)
WHERE TN1.EstimateDate BETWEEN DATEADD(Day, -10, getdate()) AND GETDATE()
AND TN1.SalesRepCode = $id
And TN1.TotalSellPrice > '5000'
AND TN1.EstimateStatus = 'P')
SELECT TOP (20)
EstimateNumber,
RevisionNumber,
CustName,
JobDescription,
TotalSellPrice,
EstimateStatus,
EstimateDate,
CommissionTableA
FROM CTE
WHERE RN = 1;
With some minor changes, it might work, As there is no data sample:
SELECT Top 20
EstimateNumber,CustName,JobDescription,TotalSellPrice,EstimateStatus,EstimateDate,CommissionTableA
FROM [dbo].[tablename1] tt
LEFT JOIN
(
--Top 20 quotes Last EstimateNumber with revision
SELECT T20.RevisionFree_EstimateNumber +
CONVERT(VARCHAR,
MAX(CONVERT(INT,
SUBSTRING(t.EstimateNumber, CHARINDEX('-', EstimateNumber)+1, LEN(EstimateNumber)-CHARINDEX('-', EstimateNumber))))) Last_EstimateNumber
FROM
(
--Top 20 quotes Original EstimateNumber
SELECT DISTINCT Top 20
TotalSellPrice
,SUBSTRING(EstimateNumber, 1, CHARINDEX('-', EstimateNumber)) RevisionFree_EstimateNumber
FROM [dbo].[tablename1]
where EstimateDate BETWEEN DATEADD(Day, -10, getdate()) AND GETDATE() And TotalSellPrice > '5000' AND EstimateStatus = 'P'
Order By TotalSellPrice DESC
)AS T20
LEFT JOIN
(
SELECT *, SUBSTRING(EstimateNumber, 1, CHARINDEX('-', EstimateNumber)) RevisionFree_EstimateNumber
FROM [dbo].[tablename1]
) t
ON T20.RevisionFree_EstimateNumber = t.RevisionFree_EstimateNumber
GROUP BY T20.RevisionFree_EstimateNumber
)LastEN
ON tt.EstimateNumber = LastEN.Last_EstimateNumber
I am running this problem on SQL server
Here is my problem.
have something like this
Dataset A
FK_ID StartDate EndDate Type
1 10/1/2018 11/30/2018 M
1 12/1/2018 2/28/2019 N
1 3/1/2019 10/31/2019 M
I have a second data source I have no control over with data something like this:
Dataset B
FK_ID SpanStart SpanEnd Type
1 10/1/2018 10/15/2018 M
1 10/1/2018 10/25/2018 M
1 2/15/2019 4/30/2019 M
1 5/1/2019 10/31/2019 M
What I am trying to accomplish is to check to make sure every date within each TYPE M record in Dataset A has at least 1 record in Dataset B.
For example record 1 in Dataset A does NOT have coverage from 10/26/2018 through 11/30/2018. I really only care about when the coverage ends, in this case I want to return 10/26/2018 because it is the first date where the span has no coverage from Dataset B.
I've written a function that does this but it is pretty slow because it is cycling through each date within each M record and counting the number of records in Dataset B. It exits the loop when it finds the first one but I would really like to make this more efficient. I am sure I am not thinking about this properly so any suggestions anyone can offer would be helpful.
This is the section of code I'm currently running
else if #SpanType = 'M'
begin
set #CurrDate = #SpanStart
set #UncovDays = 0
while #CurrDate <= #SpanEnd
Begin
if (SELECT count(*)
FROM eligiblecoverage ec join eligibilityplan ep on ec.plandescription = ep.planname
WHERE ec.masterindividualid = #IndID
and ec.planbegindate <= #CurrDate and ec.planenddate >= #CurrDate
and ec.sourcecreateddate = #MaxDate
and ep.medicaidcoverage = 1) = 0
begin
SET #Result = concat('NON Starting ',format(#currdate, 'M/d/yyyy'))
BREAK
end
set #CurrDate = #CurrDate + 1
end
end
I am not married to having a function it just could not find a way to do this in queries that wasn't very very slow.
EDIT: Dataset B will never have any TYPEs except M so that is not a consideration
EDIT 2: The code offered by DonPablo does de-overlap the data but only in cases where there is an overlap at all. It reduces dataset B to:
FK_ID SpanStart SpanEnd Type
1 10/1/2018 10/25/2018 M
instead of
FK_ID SpanStart SpanEnd Type
1 10/1/2018 10/25/2018 M
1 2/15/2019 4/30/2019 M
1 5/1/2019 10/31/2019 M
I am still futzing around with it but it's a start.
I would approach this by focusing on B. My assumption is that any absent record would follow span_end in the table. So here is the idea:
Unpivot the dates in B (adding "1" to the end dates)
Add a flag if they are present with type "M".
Check to see if any not-present records are in the span for A.
Check the first and last dates as well.
So, this looks like:
with bdates as (
select v.dte,
(case when exists (select 1
from b b2
where v.dte between b2.spanstart and b2.spanend and
b2.type = 'M'
)
then 1 else 0
end) as in_b
from b cross apply
(values (spanstart), (dateadd(day, 1, spanend)
) v(dte)
where b.type = 'M' -- all we care about
group by v.dte -- no need for duplicates
)
select a.*,
(case when not exists (select 1
from b b2
where a.startdate between b2.spanstart and b2.spanend and
b2.type = 'M'
)
then 0
when not exists (select 1
from b b2
where a.enddate between b2.spanstart and b2.spanend and
b2.type = 'M'
)
when exists (select 1
from bdates bd
where bd.dte between a.startdate and a.enddate and
bd.in_b = 0
)
then 0
when exists (select 1
from b b2
where a.startdate between b2.spanstart and b2.spanend and
b2.type = 'M'
)
then 1
else 0
end)
from a;
What is this doing? Four validity checks:
Is the starttime valid?
Is the endtime valid?
Are any intermediate dates invalid?
Is there at least one valid record?
Start by framing the problem in smaller pieces, in a sequence of actions like I did in the comment.
See George Polya "How To Solve It" 1945
Then Google is your friend -- look at==> sql de-overlap date ranges into one record (over a million results)
UPDATED--I picked Merge overlapping dates in SQL Server
and updated it for our table and column names.
Also look at theory from 1983 Allen's Interval Algebra https://www.ics.uci.edu/~alspaugh/cls/shr/allen.html
Or from 2014 https://stewashton.wordpress.com/2014/03/11/sql-for-date-ranges-gaps-and-overlaps/
This is a primer on how to setup test data for this problem.
Finally determine what counts via Ranking the various pairs of A vs B --
bypass those totally Within, then work with earliest PartialOverlaps, lastly do the Precede/Follow items.
--from Merge overlapping dates in SQL Server
with SpanStarts as
(
select distinct FK_ID, SpanStart
from Coverage_B as t1
where not exists
(select * from Coverage_B as t2
where t2.FK_ID = t1.FK_ID
and t2.SpanStart < t1.SpanStart
and t2.SpanEnd >= t1.SpanStart)
),
SpanEnds as
(
select distinct FK_ID, SpanEnd
from Coverage_B as t1
where not exists
(select * from Coverage_B as t2
where t2.FK_ID = t1.FK_ID
and t2.SpanEnd > t1.SpanEnd
and t2.SpanStart <= t1.SpanEnd)
),
DeOverlapped_B as
(
Select FK_ID, SpanStart,
(select min(SpanEnd) from SpanEnds as e
where e.FK_ID = s.FK_ID
and SpanEnd >= SpanStart) as SpanEnd
from SpanStarts as s
)
Select * from DeOverlapped_B
Now we have something to feed into the next steps, and we can use the above as a CTE
======================================
with SpanStarts as
(
select distinct FK_ID, SpanStart
from Coverage_B as t1
where not exists
(select * from Coverage_B as t2
where t2.FK_ID = t1.FK_ID
and t2.SpanStart < t1.SpanStart
and t2.SpanEnd >= t1.SpanStart)
),
SpanEnds as
(
select distinct FK_ID, SpanEnd
from Coverage_B as t1
where not exists
(select * from Coverage_B as t2
where t2.FK_ID = t1.FK_ID
and t2.SpanEnd > t1.SpanEnd
and t2.SpanStart <= t1.SpanEnd)
),
DeOverlapped_B as
(
Select FK_ID, SpanStart,
(select min(SpanEnd) from SpanEnds as e
where e.FK_ID = s.FK_ID
and SpanEnd >= SpanStart) as SpanEnd
from SpanStarts as s
),
-- find A row's coverage
ACoverage as (
Select
a.*, b.SpanEnd, b.SpanStart,
Case
When SpanStart <= StartDate And StartDate <= SpanEnd
And SpanStart <= EndDate And EndDate <= SpanEnd
Then '1within' -- starts, equals, during, finishes
When EndDate < SpanStart
Or SpanEnd < StartDate
Then '3beforeAfter' -- preceeds, meets, preceeded, met
Else '2overlap' -- one or two ends hang over spanStart/End
End as relation
From Coverage_A a
Left Join DeOverlapped_B b
On a.FK_ID = b.FK_ID
Where a.Type = 'M'
)
Select
*
,Case
When relation1 = '2' And StartDate < SpanStart Then StartDate
When relation1 = '2' Then DateAdd(d, 1, SpanEnd)
When relation1 = '3' Then StartDate
End as UnCoveredBeginning
From (
Select
*
,SUBSTRING(relation,1,1) as relation1
,ROW_NUMBER() Over (Partition by A_ID Order by relation, SpanStart) as Rownum
from ACoverage
) aRNO
Where Rownum = 1
And relation1 <> '1'
I am having two tables TblEnquiry with Enquiry _No as Primary Key and tblHistory for maintaing updatiing details with Enquiry_No as foreign key and History_CreatedOn field for date.
I want to get Enquiries which have not been updated since last 7 days.
SELECT e.*
FROM tblEnquiry e
WHERE NOT EXISTS(SELECT * FROM tblHistory h WHERE e.Enquiry_No = e.Enquiry_No AND h.History_CreatedOn >= DATEADD(dd, -7, GETDATE())
If you're using SQL Server:
SELECT
<add columns here>
FROM
tblEnquiry
WHERE
NOT EXISTS
(
SELECT *
FROM tblHistory H
WHERE H.enquiry_no = E.enquiry_no
AND H.history_createdon BETWEEN DATEADD(dy, -7, GETDATE()) AND GETDATE()
)
WITH Hist(enquiry_no, history_createdon) AS
(
SELECT Enquiry_No, History_CreatedOn
FROM tblHistory
WHERE History_CreatedOn >= DATEADD(dd, -7, GETDATE())
)
SELECT *
FROM tblEnquiry
LEFT OUTER JOIN Hist ON tblHist.enquiry_no = tblEnquiry.enquiry_no
WHERE tblHistory.enquiry_no IS NULL
This will avoid the poor performance of the standard NOT EXISTS query
Got the answer
select h1.Enquiry_No
from tblHistory h1
group by h1.Enquiry_No
having DATEDIFF(DD,Max(h1.History_CreatedOn),GETDATE())>=7
I got the Enquiries that have not been updated since last 7 days