I want to get last values for prevous month (universal, not just for january :))
How can I set up where condition? Now it works well for current month, but i want result for prevous.
SELECT MAX(v.timestamp) AS Date,
MAX(v.value) AS Stanje,
v.tag_id, t.prik_sifr, t.tag_name
FROM dbo.tag_values AS v INNER JOIN
dbo.typ_tag AS t ON v.tag_id = t.id
WHERE (t.prik_sifr IS NOT NULL) AND (t.unit = 'M3') AND
(DATEPART(YEAR, v.timestamp) = DATEPART(YEAR, SYSDATETIME())) AND
(DATEPART(MONTH, v.timestamp)= DATEPART(MONTH, SYSDATETIME())) GROUP BY v.tag_id, t.prik_sifr, t.tag_name)
You need to subtruct one month from the current date:
SELECT MAX(v.timestamp) AS Date,
MAX(v.value) AS Stanje,
v.tag_id, t.prik_sifr, t.tag_name
FROM dbo.tag_values AS v INNER JOIN
dbo.typ_tag AS t ON v.tag_id = t.id
WHERE (t.prik_sifr IS NOT NULL) AND (t.unit = 'M3') AND
(DATEPART(YEAR, v.timestamp) = DATEPART(YEAR, DATEADD(MONTH, -1 SYSDATETIME()))) AND
(DATEPART(MONTH, v.timestamp)= DATEPART(MONTH, DATEADD(MONTH, -1 SYSDATETIME())))
GROUP BY v.tag_id, t.prik_sifr, t.tag_name)
Related
I am building a report where I need to display the number of days an item was with a customer in the chosen month.
#Month is set as a parameter and the report is filtered based on the month a user chooses.
I have DATEDIFF(d, dbo.Rental.StartDateTime, { fn NOW() }) + 1 AS [Days Live] however this isn't what I need.
A rental could start before the chosen month or part way through. It could end and any date in the chosen month or not have been ended at all. so for example if running the report for November (assuming i am now in December) i could have a rental that started (dbo.Rental.StartDateTime) 15th October and ended (dbo.Rental.EndDateTime) 11th November. I would need the field to say 11 however if there is no end date i would need it to say 30
I have formatted both fields to be dd/mm/yyy. The dataset is also doing various other things in terms of displaying the relevant records.
My entire dataset is below.
SELECT TOP (100) PERCENT System_1.SystemTypeId, System_1.Id, System_1.CancellationCode, System_1.RentalId, Format(System_1.CreatedOnDateTime, 'dd/MM/yyyy') AS [Assembled Date],
Format(dbo.Rental.StartDateTime, 'dd/MM/yyyy') AS [Start Date], DATEPART(month, dbo.Rental.StartDateTime) AS [Start Date Month], dbo.Rental.Revision, dbo.Rental.RentalNumber, dbo.Rental.RentalStatus, dbo.Customer.Name AS Customer, dbo.Site.Name AS Site,
dbo.Location.Name AS Location, dbo.Rental.SpecialInstructions, DATEDIFF(d, dbo.Rental.StartDateTime, { fn NOW() }) + 1 AS [Days Live], dbo.SystemType.Description, Format(dbo.Rental.EndDateTime,
'dd/MM/yyyy') AS [End Date], DATEPART(month, dbo.Rental.EndDateTime) AS [End Date Month]
FROM dbo.SystemType INNER JOIN
dbo.System AS System_1 INNER JOIN
dbo.Contract ON System_1.ContractId = dbo.Contract.Id INNER JOIN
dbo.Customer ON dbo.Contract.CustomerId = dbo.Customer.Id ON dbo.SystemType.Id = System_1.SystemTypeId LEFT OUTER JOIN
dbo.Location INNER JOIN
dbo.Rental ON dbo.Location.Id = dbo.Rental.LocationId INNER JOIN
dbo.Site ON dbo.Location.SiteId = dbo.Site.Id ON System_1.Id = dbo.Rental.SystemId
WHERE (dbo.Rental.RentalStatus NOT LIKE 'PendingActivations') AND dbo.customer.ID = #Customer AND ((DATEPART(month, dbo.Rental.StartDateTime) = #Month) OR (DATEPART(month, dbo.Rental.EndDateTime) = #Month) OR ( (DATEPART(month, dbo.Rental.StartDateTime) < #Month) AND (dbo.Rental.EndDateTime IS NULL )))
ORDER BY System_1.Id
I am trying to tally all Invoices without Sales Order and show it as an SQL query. The date should be the Invoices entered yesterday. The challenge is it seems that the result is static and won't change
SELECT TOP (100) PERCENT CONVERT(varchar, DATEADD(dd, - 1, GETDATE()), 103) AS Date,
'Invoices w/o SO' AS Type,
COUNT(dbo.Invoice.InvoiceID) AS Orders,
COUNT(dbo.Invoice.InvoiceID) AS Chairs,
ISNULL(ROUND(SUM(dbo.InvoiceDetails.ExtendedPrice), 2), 0) AS [Total Ex GST]
FROM dbo.Invoice INNER JOIN dbo.Customers
ON dbo.Invoice.CustomerID = dbo.Customers.CustomerID
INNER JOIN dbo.InvoiceDetails
ON dbo.Invoice.InvoiceID = dbo.InvoiceDetails.InvoiceID
WHERE (dbo.InvoiceDetails.ItemNo = 'TRIAL CHAIR')
OR
(dbo.InvoiceDetails.ItemNo = 'STORAGE')
OR
(dbo.InvoiceDetails.ItemNo = 'RSTF01')
OR
(dbo.InvoiceDetails.ItemNo = 'FRDMC01')
AND
(dbo.Invoice.CredInvoiceNo IS NULL)
AND
(dbo.Invoice.EntryDate >= CONVERT(char(8), DATEADD(dd, - 1, GETDATE()), 112))
AND
(dbo.Customers.CustomerID <> 187)
Screenshot
Thanks everyone.
I changed the query and it worked!
SELECT
CONVERT(varchar, DATEADD(dd, -1, GETDATE()), 103) AS Date,
'Invoices w/o SO' AS Type,
COUNT(dbo.Invoice.InvoiceID) AS Orders,
COUNT(dbo.Invoice.InvoiceID) AS Chairs,
ISNULL(ROUND(SUM(dbo.InvoiceDetails.ExtendedPrice), 2), 0) AS [Total Ex GST]
FROM dbo.Invoice
INNER JOIN dbo.Customers
ON dbo.Invoice.CustomerID = dbo.Customers.CustomerID
INNER JOIN dbo.InvoiceDetails
ON dbo.Invoice.InvoiceID = dbo.InvoiceDetails.InvoiceID
WHERE (dbo.InvoiceDetails.ItemNo IN ('TRIAL CHAIR', 'STORAGE', 'RSTF01', 'FRDMC01'))
AND (dbo.Invoice.CredInvoiceNo IS NULL)
AND (dbo.Customers.CustomerID <> 187)
AND (DATEDIFF(DAY, dbo.Invoice.EntryDate, GETDATE()) = 1)
I'm trying to filter only events that happened within 30 days after the company was created (RegisteredUtc).
Does anyone know how to rewrite this query to make sure that predicate uses the index that exists?
I've tried both with an index that has (eventtype, timeutc) and includes (companyid) and one that has (eventtype) and includes (companyid, timeutc).
This is the query that does what I want. NOTE: between these 3 queries it's only the last predicate in the first where clause that changes.
select
DATEPART(year, q.RegisteredUtc) as [year],
DATEPART(month, q.RegisteredUtc) as [month],
Count(*) as [Count]
from
(select
c.Id,
c.RegisteredUtc,
(select count(*)
from dbo.events sc
where sc.companyId = c.Id
and sc.eventtype = 'CreateInvoice'
and sc.TimeUtc < DATEADD(day, 30, c.RegisteredUtc)) as [Count]
from
dbo.companies c) as q
where
q.Count > 0
group by
DATEPART(year, q.RegisteredUtc), DATEPART(month, q.RegisteredUtc)
But it's very slow because of the and TimeUtc < DATEADD(day, 30, c.RegisteredUtc). Without that it uses the indexes and runs very fast but with that predicate there it does a Eager spool that is very expensive instead of using the index.
There are actually indexes available. Confirmed by simply swapping DATEADD(day, 30, c.RegisteredUtc)with a constant which made the query fast again.
This is also slow.
select
DATEPART(year, q.RegisteredUtc) as [year],
DATEPART(month, q.RegisteredUtc) as [month],
Count(*) as [Count]
from
(select
c.Id,
c.RegisteredUtc,
(select count(*)
from dbo.events sc
where sc.companyId = c.Id
and sc.eventtype = 'CreateInvoice'
and sc.TimeUtc < c.RegisteredUtc) as [Count]
from
dbo.companies c) as q
where
q.Count > 0
group by
DATEPART(year, q.RegisteredUtc), DATEPART(month, q.RegisteredUtc)
This query hits the index and works fast though but of course doesn't produce the correct results.
select
DATEPART(year, q.RegisteredUtc) as [year],
DATEPART(month, q.RegisteredUtc) as [month],
Count(*) as [Count]
from
(select
c.Id,
c.RegisteredUtc,
(select count(*)
from dbo.events sc
where sc.companyId = c.Id
and sc.eventtype = 'CreateInvoice'
and sc.TimeUtc = c.RegisteredUtc) as [Count]
from
dbo.companies c) as q
where
q.Count > 0
group by
DATEPART(year, q.RegisteredUtc), DATEPART(month, q.RegisteredUtc)
As I see it you are not even using the inner count
If it matches the join then the count > 0
select DATEPART(year, q.RegisteredUtc) as [year],
DATEPART(month, q.RegisteredUtc) as [month],
Count(*) as [Count]
from ( select distinct c.Id, c.RegisteredUtc
from dbo.companies c
join dbo.events sc
on sc.companyId = c.Id
and eventtype = 'CreateInvoice'
and TimeUtc < DATEADD(day, 30, c.RegisteredUtc)
) as q
group by DATEPART(year, q.RegisteredUtc), DATEPART(month, q.RegisteredUtc)
where exists may work better. Your query is confusing to me. You get a count just to compare it to > 0 and you are worried about not using an in index?
It might be worthwhile to compute the DATEADD(day, 30, c.RegisteredUtc) in the select and then compare TimeUtc with the computed column, in other words:
select
c.Id,
c.RegisteredUtc,
DATEADD(day, 30, c.RegisteredUtc) as RegisteredUtc30
(
select count(*)
from dbo.events sc
where sc.companyId = c.Id
and sc.eventtype = 'CreateInvoice'
and sc.TimeUtc < RegisteredUtc30
from dbo.companies c
In SQL-server database I want to update the table1 with the value of table2, I have two tables pay_tbl and bill_tbl. Those two have the following attributes.
pay_tbl
pay_ID type int -->pk
outstanding_amount type int
bill_tbl
pay_ID type int --> Fk
amount_to_Pay type int
amount_paid type int
paid_date type date
bill_status type varchar
I want to update the outstanding_amount column of pay_tbl by adding the value of amount_to_pay column of table2
(outstanding_payment+=amount_to_pay)
but just update those where bill status is 'Not Paid' and date is last month with respect to current month, i.e: now month is February then only update table where date is in Janurary. I tried following query but I know it is wrong
UPDATE pay_tbl
SET
outstanding_payment = outstanding_Payment +
(SELECT
amount_to_pay
FROM bill_tbl INNER JOIN bill_tbl ON
bill_tbl.pay_ID = pay_tbl.payID )
WHERE
MONTH(Date) = DATEPART(MONTH, DATEADD(MONTH, -1, [Date]))
AND YEAR(Date) = DATEPART(YEAR, DATEADD(MONTH, -1, [Date]))
UPDATE
TABLE_A
SET
TABLE_A.OUTSTANDING_PAYMENT = TABLE_A.OUTSTANDING_PAYMENT+TABLE_B.AMOUNT_TO_PAY
FROM
PAY_TBL AS TABLE_A
INNER JOIN (SELECT SUM(AMOUNT_TO_PAY) AMOUNT_TO_PAY ,PAY_ID FROM BILL_TBL WHERE MONTH(DATE) = DATEPART(MONTH, DATEADD(MONTH, -1, [DATE]))
AND YEAR(DATE) = DATEPART(YEAR, DATEADD(MONTH, -1, [DATE]))
AND BILL_STATUS='NO PAID'
GROUP BY PAY_ID) AS TABLE_B
ON TABLE_A.PAY_ID = TABLE_B.PAY_ID
I have to get the list of months and year in between my dates. Currently it only returns month and year for dates that has data associated with it.
for example my dates is between: '8'+'/1'+'/'+'2015' and DATEADD(mm, 15, '8'+'/1'+'/'+'2016'
It only prints out: May2016, June2016, July2016, Auguest2016, September2016
I want it to print out all of the months and year in between. Here is my sql queries:
select d.id_base as case_id,
c.C_LAST_ACTION AS Docketed,
c.C_CASE_TYPE AS caseType,
ct.C_NAME As caseName,
ct.C_DESCRIPTION AS caseNameDescription,
case when d.c_mod_decision_id is not null then '' else DATENAME(mm, d.c_issue_date) + DATENAME(yyyy, d.c_issue_date) end as display
from t_case_decision d JOIN T_CASE_INPUT c on c.id = d.id_base JOIN T_CASE_TYPE ct on C_CASE_TYPE = ct.id
where cast(d.c_issue_date AS date) BETWEEN '8'+'/1'+'/'+'2015' and DATEADD(mm, 15, '8'+'/1'+'/'+'2016')
First, create a numbers table
CREATE TABLE Numbers(N INT)
insert into Numbers(N)
select top 1000000 row_number() over(order by t1.number) as N
from master..spt_values t1
cross join master..spt_values t2
then use DATEADD to list dates between desired values, like this
declare #iniDate as date
set #iniDate='20150801'
select dateadd(MONTH,N,#iniDate) dates
from Numbers
where N<15 order by N
These returns dates from #iniDate up to 15 months later
EDIT: try this, I don't have sql right now
select datename(mm, dateadd(MONTH,N,#iniDate))+datename(yyyy ,dateadd(MONTH,N,#iniDate)) display
from ( select top 15row_number() over(order by t1.number) as N
from master..spt_values t1
cross join master..spt_values t2) numbers right join (
select d.id_base as case_id,
c.C_LAST_ACTION AS Docketed,
c.C_CASE_TYPE AS caseType,
ct.C_NAME As caseName,
ct.C_DESCRIPTION AS caseNameDescription,
case when d.c_mod_decision_id is not null then '' else DATENAME(mm, d.c_issue_date) + DATENAME(yyyy, d.c_issue_date) end as display
from t_case_decision d JOIN T_CASE_INPUT c on c.id = d.id_base JOIN T_CASE_TYPE ct on C_CASE_TYPE = ct.id
where cast(d.c_issue_date AS date) BETWEEN '8'+'/1'+'/'+'2015' and DATEADD(mm, 15, '8'+'/1'+'/'+'2016')
sql-server
) qq
on datename(mm, dateadd(MONTH,N,#iniDate))+datename(yyyy ,dateadd(MONTH,N,#iniDate)) = qq.display
where N<15 order by N
If I understand what you're trying to accomplish, a recursive CTE might help. Here's a quick example of what you can do. The CTE will expand out into a list of dates, which you can then use as the base for your query.
The contents of the TargetData CTE may need to be adjusted, as I don't have a complete picture of your data structure.
DECLARE #startDate DATE = '1/1/2015';
DECLARE #endDate DATE = '7/31/2016';
-- Recursive CTE to generate a list of months within the date range:
WITH Months AS (
SELECT CONVERT(DATE, DATEADD(D, -(DAY(#startDate)) + 1, #startDate)) [MonthDate]
UNION ALL
SELECT DATEADD(M, 1, MonthDate)
FROM Months
WHERE MonthDate <= DATEADD(M, -1, #endDate)
),
TargetData AS (
-- This is a slightly modified version of the original query:
select
d.id_base as case_id,
c.C_LAST_ACTION AS Docketed,
c.C_CASE_TYPE AS caseType,
ct.C_NAME As caseName,
ct.C_DESCRIPTION AS caseNameDescription,
case when d.c_mod_decision_id is not null then '' else DATENAME(mm, d.c_issue_date) + DATENAME(yyyy, d.c_issue_date) end as display,
-- Return the "MonthDate" so that it can be left joined to the Months table:
DATEADD(D, -(DAY(d.c_issue_date)) + 1, d.c_issue_date) [MonthDate]
from t_case_decision d JOIN T_CASE_INPUT c on c.id = d.id_base JOIN T_CASE_TYPE ct on C_CASE_TYPE = ct.id
where cast(d.c_issue_date AS date) BETWEEN #startDate AND #endDate
)
SELECT
m.MonthDate,
DATENAME(mm, m.MonthDate) + DATENAME(yyyy, m.MonthDate),
td.*
FROM Months m
LEFT JOIN TargetData td ON td.MonthDate = m.MonthDate;
You need to join on primary keys between tables, I haven't seen a between statement with that syntax. So I suggest trying the following:
SELECT d.id_base as case_id, c.C_LAST_ACTION AS 'Docketed',c.C_CASE_TYPE AScaseType,ct.C_NAME As 'caseName', ct.C_DESCRIPTION AS 'caseNameDescription'
,CASE
WHEN d.c_mod_decision_id is not null THEN '' AS 'null_val'
ELSE CONCAT(YEAR(d.c_issue_dateDATENAME), MONTH(d.c_issue_date))
END AS 'display'
FROM t_case_decision d INNER JOIN T_CASE_INPUT c on c.id = d.id_base
INNER JOIN T_CASE_TYPE ct on c.id = ct.id
WHERE CONVERT(DATE,d.c_issue_date) BETWEEN '08/01/2015'
AND '08/01/2016';
I hope this helps or points you in the right direction :)