I am trying to use HAVING after a GROUP BY but I get this error:
SELECT list expression references sales_order.SalesOrderDateTime
which is neither grouped nor aggregated at [2:8]
The field is in the SELECT list, and GROUP BY, but it is part of a CAST because I do not want the timestamp part of the datetime. It works without the CAST on another table where the format is already YYYY-MM-DD. It really should work here as well. Is there a way around this?
I tried using STRING FORMAT 'YYYY-MM-DD' but that does not work either.
SELECT
CAST(sales_order.SalesOrderDateTime AS DATE) as created_at,
sales_order.SalesOrderNo as order_id,
sales_order.SellToEmail as customer_email,
sum(sales_order_item.OriginalPrice)*100 as total_amount_cents,
max(sales_order.TotalDiscountAmount)*100 as discount_amount_cents
FROM `my_dw.external_datamart_1.SalesOrder_view`
WHERE CAST(sales_order.SalesOrderDateTime AS DATE) >= '2022-01-01'
GROUP BY CAST(sales_order.SalesOrderDateTime AS DATE), sales_order.SalesOrderNo, sales_order.SellToEmail
-- This does not work with CAST
HAVING sum(sales_order_item.OriginalPrice) > max(sales_order.TotalDiscountAmount)
LIMIT 1000
)
A CTE works of course, but I would like to avoid that if possible.
You can try this:
group by 1,2,3
instead of using full expressions.
I face the same issue time to time in my complex queries. I think it's a bug and can be reported here https://issuetracker.google.com/
Related
I'm trying to add a wildcard to my date select query so i only pull the day not time. I.e. 2021-03-11 17:54:30.123. I thought a number could be substituted for a #.
select AID, LocalCoAltIn,LocalCoAltOut,EventTime
from EXCDS.dbo.WKS_LOG_VIEW
where EventTime like '2021-03-11 ##:##:##:###';
My query is returning no values even though they are in the table. Thanks.
No! Don't use strings! One method is to convert to a date:
select AID, LocalCoAltIn,LocalCoAltOut,EventTime
from EXCDS.dbo.WKS_LOG_VIEW
where convert(date, EventTime) = '2021-03-11';
Another method is to use a range:
where EventTime >= '2021-03-11' and
EventTime < '2021-03-12'
The LIKE operator in most flavors of SQL only support _ and * wildcards (matching any one single, or multiple characters). Gordon has given you a better approach, but if you wanted to fix your current query on SQL Server you could try:
SELECT AID, LocalCoAltIn, LocalCoAltOut, EventTime
FROM EXCDS.dbo.WKS_LOG_VIEW
WHERE EventTime LIKE '2021-03-11 [0-9][0-9]:[0-9][0-9]:[0-9][0-9]:[0-9][0-9][0-9]';
SQL Server extended the LIKE operator to accept a few extra things, such as character classes. Here [0-9] inside LIKE would match any single digit.
Not sure that like operator would work for date as you want, but you still have few options.
Use DATEPART function to retrieve year\month\etc and compare it with exact value that you need
select AID, LocalCoAltIn,LocalCoAltOut,EventTime from EXCDS.dbo.WKS_LOG_VIEW where DATEPART(year,EventTime) = 2021 AND DATEPART(month,EventTime) = 3 AND DATEPART(day,EventTime = 11);
Or use Gordon Linoff suggestion if you dont care about exact date part and only need to compare entire date without time
I'm trying to create a custom query in Tableau to use on Google's BigQuery. The goal is to have an offset parameter in Tableau that changes the offsets used in a date based WHERE clause.
In Tableau it would look like this:
SELECT
DATE_ADD(UTC_USEC_TO_MONTH(CURRENT_DATE()),<Parameters.Offset>-1,"MONTH") as month_index,
COUNT(DISTINCT user_id, 1000000) as distinct_count
FROM
[Orders]
WHERE
order_date >= DATE_ADD(UTC_USEC_TO_MONTH(CURRENT_DATE()),<Parameters.Offset>-12,"MONTH")
AND
order_date < DATE_ADD(UTC_USEC_TO_MONTH(CURRENT_DATE()),<Parameters.Offset>-1,"MONTH")
However, BigQuery always returns an error:
Error: DATE_ADD 2nd argument must have INT32 type.
When I try the same query in the BigQuery editor using simple arithmetic it fails with the same error.
SELECT
DATE_ADD(UTC_USEC_TO_MONTH(CURRENT_DATE()),5-3,"MONTH") as month_index,
FROM [Orders]
Any workaround for this? My only option so far is to make multiple offsets in Tableau, it seems.
Thanks for the help!
I acknowledge that this is a hole in functionality of DATE_ADD. It can be fixed, but it will take some time until fix is rolled into production.
Here is a possible workaround. It seems to work if the first argument to DATE_ADD is a string. Then you can truncate the result to a month boundary and convert it from a timestamp to a string.
SELECT
FORMAT_UTC_USEC(UTC_USEC_TO_MONTH(DATE_ADD(CURRENT_DATE(),5-3,"MONTH"))) as month_index;
The date in my table looks like 2010-06-16 00:00:00.000
When I use the below regular expression, no rows get selected.
select mydate from mytable where mydate like '2010%'
However, when I use this one, rows do get selected correctly.
select mydate from mytable where mydate like '%2010%'
So, I thought that probably leading white spaces are getting added. To take those into account, I used the below query. But this doesn't work either.
select mydate from mytable where LTRIM(RTRIM(mydate)) like '2010%'
Since the first one works, it means, that there is something before the 2010? What else apart from white spaces, could it be? I tried pasting it onto a text file, and don't see anything.
If the datatype is Datetime you should use Year() function to filter the rows instead of like. You should not use like operator to filter the data from Datetime type.
If the datatype is Datetime then you won't be having leading or trailing spaces.
You do have appropriate Date functions in Sql Server use those to filter the rows.
select mydate from mytable where year(mydate) = 2010
or even Datepart
select mydate from mytable where Datepart(YYYY,mydate) = 2010
You have to convert datetime that first in varchar to use like
select mydate from mytable
WHERE CONVERT(VARCHAR(10),mydate,120) like '2010%'
DEMO
You probably should use just date range fetches, for example
select mydate from mytable where mydate >= '20100101' and mydate < '20110101'
Using functions for the column (e.g. year(mydate)) is not a good idea because then indexes can't be used. Using 'between' can also cause problems with datetime columns because the time part can cause you to accidentally leave out rows.
The reason you found something with your search is probably due to typecasting the date into varchar before comparison, and format is such that the year is at the end, but please don't use that.
I have a query in which I want to select data from a column where the data is a date. The problem is that the data is a mix of text and dates.
This bit of SQL only returns the longest text field:
SELECT MAX(field_value)
Where the date does occur, it is always in the format xx/xx/xxxx
I'm trying to select the most recent date.
I'm using MS SQL.
Can anyone help?
Try this using ISDATE and CONVERT:
SELECT MAX(CONVERT(DateTime, MaybeDate))
FROM (
SELECT MaybeDate
FROM MyTable
WHERE ISDATE(MaybeDate) = 1) T
You could also use MAX(CAST(MaybeDate AS DateTime)). I got in the (maybe bad?) habit of using CONVERT years ago and have stuck with it.
To do this without a conversion error:
select max(case when isdate(col) = 1 then cast(col as date) end) -- or use convert()
from . . .
The SQL statement does not specify the order of operations. So, even including a where clause in a subquery will not guarantee that only dates get converted. In fact, the SQL Server optimizer is "smart" enough to do the conversion when the data is brought in and then do the filtering afterwards.
The only operation that guarantees sequencing of operations is the case statement, and there are even exceptions to that.
Another solution would be using PATINDEX in WHERE clause.
SELECT PATINDEX('[0-9][0-9]/[0-9][0-9]/[0-9][0-9][0-9][0-9]', field_value)
Problem with this approach is you really are not sure if something is date (e.g. 99/99/9999 is not date).
And problem with IS_DATE is it depends on configuration (e.g. DATEFORMAT).
So, use an appropriate option.
This seems stupid but, I simply need a list of dates to be ordered with the most recent date at top. Using order by DESC doesn't seem to be working the way I want it to.
SELECT *
FROM vw_view
ORDER BY EventDate DESC
It gives me the date ordered by month and day, but doesn't take year into consideration.
for example:
12/31/2009
12/31/2008
12/30/2009
12/29/2009
Needs to be more like:
12/31/2009
12/30/2009
12/29/2009
12/28/2009
and so on.
I'm guessing EventDate is a char or varchar and not a date otherwise your order by clause would be fine.
You can use CONVERT to change the values to a date and sort by that
SELECT *
FROM
vw_view
ORDER BY
CONVERT(DateTime, EventDate,101) DESC
The problem with that is, as Sparky points out in the comments, if EventDate has a value that can't be converted to a date the query won't execute.
This means you should either exclude the bad rows or let the bad rows go to the bottom of the results
To exclude the bad rows just add WHERE IsDate(EventDate) = 1
To let let the bad dates go to the bottom you need to use CASE
e.g.
ORDER BY
CASE
WHEN IsDate(EventDate) = 1 THEN CONVERT(DateTime, EventDate,101)
ELSE null
END DESC
try ORDER BY MONTH(Date),DAY(DATE)
Try this:
ORDER BY YEAR(Date) DESC, MONTH(Date) DESC, DAY(DATE) DESC
Worked perfectly on a JET DB.
You have the field in a string, so you'll need to convert it to datetime
order by CONVERT(datetime, EventDate ) desc
Assuming that you have the power to make schema changes the only acceptable answer to this question IMO is to change the base data type to something more appropriate (e.g. date if SQL Server 2008).
Storing dates as mm/dd/yyyy strings is space inefficient, difficult to validate correctly and makes sorting and date calculations needlessly painful.
what is the type of the field EventDate, since the ordering isn't correct i assume you don't have it set to some Date/Time representing type, but a string. And then the american way of writing dates is nasty to sort
If you restructured your date format into YYYY/MM/DD then you can use this simple string ordering to achieve the formating you need.
Alternatively, using the SUBSTR(store_name,start,length) command you should be able to restructure the sorting term into the above format
perhaps using the following
SELECT *
FROM vw_view
ORDER BY SUBSTR(EventDate,6,4) + SUBSTR(EventDate, 0, 5) DESC
Try this
SELECT *
FROM vw_view
ORDER BY DATE_FORMAT(EventDate, "%m-%d-%y") DESC