I can't understand why this is giving me the error "Cannot construct data type date, some of the arguments have values which are not valid."
This is my query:
SELECT TOP 1 pc.Comment AS [Comment], pc.[Month] AS [Month], pc.[Year] AS [Year]
FROM PECCS.dbo.ProjectComment pc
WHERE pc.ProjectId = 11501 AND
pc.Type = 'OYEO' AND
(DATEFROMPARTS(pc.[Year], pc.[Month], 1) <= DATEFROMPARTS(2017, 12, 1)) AND
pc.ResourceCategoryID = 1
ORDER BY pc.[Year] DESC, pc.[Month] DESC
The parameters that I am passing are valid. What I believe is the problem is that there are records in the table where Month = 0. I believe that's causing the problem here: (DATEFROMPARTS(pc.[Year], pc.[Month], 1)
Is [Month] an INT column in your database, or a VARCHAR with the name of the month spelled out? Using similar columns to test this, it gives me the same error, until I changed [Month] to a different column [Month of Year], which is INT. Then it works fine.
I solved the issue by converting those months where it is 0 to a default Month value. In this case, I chose 12:
SELECT TOP 1 pc.Comment AS [Comment], pc.[Month] AS [Month], pc.[Year] AS [Year]
FROM PECCS.dbo.ProjectComment pc
WHERE pc.ProjectId = 11501 AND
pc.Type = 'OYEO' AND
(DATEFROMPARTS(pc.Year, CASE WHEN pc.[Month] = 0 THEN 12 ELSE pc.[Month] END, 1) <= DATEFROMPARTS(#Year, #Month, 1)) AND
pc.ResourceCategoryID = 1
ORDER BY pc.[Year] DESC, pc.[Month] DESC
Related
I have the following query: (simplified to one year)
WITH myTable
AS (SELECT cv.Company,
cv.Zip,
DATEPART(year, od.OrderDate) AS TheYear,
'' + DATEPART(year, od.OrderDate) AS TheYear2,
od.OrderNumber AS countOrders,
STUFF(
(
SELECT '| ' + FORMAT(DateVisited, 'MM-yyyy') + ' ' + MeetingType + ' '
FROM CustomerVisits cv1
WHERE(RIGHT(od.Email, LEN(od.Email) - CHARINDEX('#', od.email))) = cv1.EmailDomain
AND cv1.Zip = od.Zip
GROUP BY MeetingType,
FORMAT(DateVisited, 'MM-yyyy')
ORDER BY FORMAT(DateVisited, 'MM-yyyy') ASC FOR XML PATH('')
), 1, 1, '') AS Meetings,
od.FinalProductTotal AS total
FROM orders od
LEFT JOIN CustomerVisits cv ON od.Zip = cv.Zip
WHERE(RIGHT(od.Email, LEN(od.Email) - CHARINDEX('#', od.email))) = cv.EmailDomain
--AND od.OrderDate > #fromDate
AND approved = 1
AND cancelled = 0
AND od.OrderDate > '01-JAN-2010')
--and the PIVOT
SELECT Company,
Zip,
Meetings,
[02020] AS [Orders - 2020],
ISNULL(CAST([2020] AS INT), 0) AS [Total - 2020],
Total = CAST((SUM(ISNULL([2020], 0))) AS INT)
FROM myTable PIVOT(COUNT(countOrders) FOR TheYear2 IN([02020])) AS myPvt PIVOT(SUM(total) FOR TheYear IN([2020])) AS myPvt2
GROUP BY Company,
zip,
Meetings,
[2020],
[02020];
For it I'm trying to add the count of orders for each year, but I'm having problems understanding how should I proceed, I might be complicating it too much, but I'm not getting the proper count
I think that the myTable table is getting properly the "countOrders" but I'm not sure if I'm doing it properly on the pivot table to group by them and show the count by year
right now it kinda seems that is counting all the orders as I needed, however when I manually check on the DB seems that the data is off.
also, something I don't understand is why is it repeating the "company" so many times when I'm doing grouping by it?
example
I ended up case instead of pivot table. this solved the issue, with format:
CAST(SUM(CASE WHEN TheYear = 2010 THEN 1 ELSE 0 END)AS INT) AS [Orders - 2010] ,
CAST(SUM(CASE WHEN TheYear = 2010 THEN Total ELSE 0 END)AS INT) AS [Total - 2010],
in case it works for someone :)
I am trying to grab the last (latest) blog article's link for each month using a stored procedure but I cannot seem to find a way past my problem.
Currently, my code below repeats the (the latest blog article's) 'LINK' column like so:
SELECT AVG(DATEPART(mm, b.blog_date)) AS MonthNum --CANNOT USE MONTHNUM IN ORDER BY UNLESS WRAPPED WITH AVG() [average], weird but works
, CAST(DateName(month, DateAdd(month, Datepart(MONTH, b.blog_date), -1)) AS varchar(24)) AS MONTH
, CAST(DATEPART(YEAR, b.blog_date) AS varchar(4)) AS YEAR
, CAST(count(b.blog_content) AS varchar(24)) as ARTICLES
, (SELECT TOP (1) b.blog_url
FROM Management.Blog
WHERE (website_owner_id = 2)
GROUP BY blog_date
, blog_url
ORDER BY blog_date DESC
) AS LINK
, CAST(DateName(month, DateAdd(month, Datepart(MONTH, b.blog_date), -1)) AS varchar(24)) + CAST(DATEPART(YEAR, b.blog_date) AS varchar(4)) AS ID
, blog_date as DATE
FROM Management.Blog b
WHERE b.website_owner_id = 2
GROUP BY CAST(DateName(month, DateAdd(month, Datepart(MONTH, b.blog_date), -1)) AS varchar(24))
, CAST(DATEPART(YEAR, b.blog_date) AS varchar(4))
, b.blog_url
, blog_date
, CAST(DateName(month, DateAdd(month, Datepart(MONTH, b.blog_date), -1)) AS varchar(24)) + CAST(DATEPART(YEAR, b.blog_date) AS varchar(4))
ORDER BY DATE DESC
I understand the code is horrible to read (& probably to execute on the SQL server too) but I'm in a position where I am only new to SQL server (coming from MySQL where I've only really had to use a basic select query) and I am open to any suggestions to changing the query and/or table design.
Essentially there should be no duplicates of the ID column (which is only really added in to assist in removing the duplicates and can be omitted if need be).
Without sample data I'm unable to test whether this would work
After FROM Management.Blog b
Add this
INNER JOIN(
SELECT MonthNum = DATEPART(MONTH, BL.blog_date))
,blog_date
,RN = ROW_NUMBER()OVER(ORDER BY BL.blog_date DESC)
,BL.blog_url
FROM Management.Blog BL
) X ON B.blog_date = X.blog_date
AND X.RN = 1
Replace
(SELECT TOP (1) b.blog_url
FROM Management.Blog
WHERE (website_owner_id = 2)
GROUP BY blog_date
, blog_url
ORDER BY blog_date DESC
) AS LINK
with
X.blog_url AS [LINK]
change this in GROUP BY
, b.blog_url
with
, x.blog_url
I non-functioning query usually does not do a very good job of conveying what someone wants. Based on your explanation:
I am trying to grab the last (latest) blog article's link for each month
I would expect something like this:
SELECT b.*
FROM (SELECT b.*,
ROW_NUMBER() OVER (PARTITION BY YEAR(b.blog_date), MONTH(b.blog_date), b.blog_url, b.website_owner_id
ORDER BY blog_date DESC
) as seqnum
FROM Management.Blog b
) b
WHERE b.website_owner_id = 2 AND
seqnum = 1;
I've written a query to get the Sum of three fields, except the majority of them sum up to be zero. I need to only return the sums that are greater than zero. Below is the Query
SELECT [Product],
SUM([Pounds]) as SumPounds,
SUM([Dollars]) as SumDollars,
SUM([EBITDA]) as SumEBITDA
FROM MyTable
WHERE ([Year] = '2017' AND [Date] <= #8/20/2017#)
SORT BY [Product];
Is there a way to only return the sums greater than zero in Access?
SELECT [Product],
SUM([Pounds]) as SumPounds,
SUM([Dollars]) as SumDollars,
SUM([EBITDA]) as SumEBITDA
FROM MyTable
WHERE ([Year] = '2017' AND [Date] <= #8/20/2017#)
GROUP BY [Product]
HAVING SUM([Pounds]) + SUM([Dollars]) + SUM([EBITDA]) > 0
You can use HAVING for filter the result of aggregated functions
SELECT [Product],
SUM([Pounds]) as SumPounds,
SUM([Dollars]) as SumDollars,
SUM([EBITDA]) as SumEBITDA
FROM MyTable
WHERE ([Year] = '2017' AND [Date] <= #8/20/2017#)
HAVING UM([Pounds]) >0 AND SUM([Dollars]) > 0 AND SUM([EBITDA]) >0
SORT BY [Product];
if you need all the 3 value you can use AND as in answer above if you need only one you can use OR
I am having problem with the datepart calculation in the Where clause of a query. The query returns result without the calculation but nothing if i add the condition.
DECLARE #StatusId INT;
SELECT #StatusId = Id FROM company.Status WHERE Name = 'Signed' AND CompanyId = 1;
SELECT FORMAT(CAST(cont.CreatedDate AS DATE), 'MM/dd') AS newDate,
SUM(CASE WHEN cont.UpdatedDate IS NOT NULL THEN 1 ELSE 0 END) AS TotalSignedLeads
FROM client.testw cont
WHERE cont.CompanyId = 1
AND cont.AffiliateId = 1
AND cont.CreatedDate BETWEEN '7-01-2017' AND '7-09-2017'
AND DATEPART(dw, cont.CreatedDate) NOT IN (1, 7) //This causes problem.
AND cont.StatusId = #StatusId
GROUP BY CAST(cont.CreatedDate AS DATE)
ORDER BY newDate ;
This is the data above query gives without the datepart condition.
newDate TotalSignedLeads
07/08 7
Well since you are casting cont.CreatedDate as a date in the top of the query, I suspect it's actually a varchar... thus you need
...
and datepart(weekday, cast(cont.CreatedDate as date)) not in (1,7)
...
bad-habits-to-kick-using-shorthand-with-date-time-operations
If you aren't getting an error, then you don't have any rows which meet that condition. Perhaps your DATEFIRST setting isn't what you think it is.
Also, not sure what GROUP BY CAST(#StatusId.CreatedDate AS DATE) is meant to be...
I suspect that you want a query more like this:
SELECT FORMAT(CAST(cont.CreatedDate AS DATE), 'MM/dd') AS newDate,
COUNT(cont.UpdatedDate) AS TotalSignedLeads
FROM client.testw cont
WHERE cont.CompanyId = 1 AND
cont.AffiliateId = 1 AND
cont.CreatedDate BETWEEN '2017-07-01' AND '2017-09-01' AND
DATEPART(dw, CAST(cont.CreatedDate AS DATE)) NOT IN (1, 7) AND //This causes problem.
cont.StatusId = #StatusId
GROUP BY FORMAT(CAST(cont.CreatedDate AS DATE), 'MM/dd')
ORDER BY newDate ;
Changes:
The dates for comparison are in a standard format, so they should be interpreted correctly.
The GROUP BY uses the same structure as the SELECT for the columns.
The SUM(CASE) is replaced by the much simpler COUNT().
The value for CreatedDate is cast as a DATE. To be honest, I'm not sure that will fix any problem, because that should be happening anyway.
Using SQL Server 2008...
I'm having some troubles in trying to order my rows in a specific order that I would like them to be ordered by. I've found a few examples that use the ORDER BY CASE clause, but am unsure whether using this method will produce the result that I want it to, thus I come to the community!
Here's what I have:
First, I select, if it exists, a distinct year that is equal to the current year:
IF EXISTS(SELECT DISTINCT [Year]
FROM Assessment WHERE ProjectCode = #ProjectCode AND [Year] = DATENAME(YEAR, GETDATE()))
SELECT DISTINCT [Year]
FROM Assessment WHERE ProjectCode = #ProjectCode
But, then I find some confusion in ordering the results. I'd like to set the current year to the first row returned using the ORDER BY clause, then order the rest of the returned years in a descending order, here's what I have so far:
ORDER BY (CASE WHEN [Year] = (DATENAME(YEAR, GETDATE())) THEN 1
ELSE 100 END) ASC, [Year] desc
Next, if the current year is not contained in the query, select each year and order by year descending.
ELSE
SELECT DISTINCT [Year]
FROM Assessment WHERE ProjectCode = #ProjectCode
ORDER BY [Year] desc
Thanks, in advance!
You don't need conditional statements here at all:
SELECT *
FROM (
SELECT DISTINCT [Year]
FROM Assessment
WHERE projectCode = #projectCode
) q
ORDER BY
CASE [Year] WHEN YEAR(GETDATE()) THEN 1 ELSE 2 END,
[Year]
will output the current year (if exists) first, the other later.
You're question isn't very clear because you don't specify what is broken or where you're having issues. From what I gather, however, you don't need an IF/ELSE. Instead you could do something like ...
SELECT DISTINCT [Year],
CASE [Year]
WHEN DATENAME(Year, GETDATE()) THEN 9999
ELSE [Year] END AS GarbageSoDistinctWorks
FROM Assessment
WHERE ProjectCode = #ProjectCode
ORDER BY
CASE [Year]
WHEN DATENAME(Year, GETDATE()) THEN 9999
ELSE [Year] END DESC
FYI ... i added the case to the select list as a throw away column to avoid the error I assume you're getting.. There are other ways, like a derived table, but for now this should work..
Msg 145, Level 15, State 1, Line 2
ORDER BY items must appear in the select list if SELECT DISTINCT is specified.
HTH,
-eric
Your example code appears to do what you describe. What problems are you having?
As a side note: You don't need the IF statement. By using the ORDER BY from your first example (with the CASE statement), you will get the correct results for both scenarios.
- If "this year" is in your data, it comes first. Everything else comes next in DESC order
- If "this year" isn't in your data, you just get everything else in DESC order