I'm trying to create an sql statement which involves adding up a total of a cost field between two dates and where a customer id is to a certain value. My statement currently looks like this:
SELECT SUM(COST) AS TotalCost
FROM ORDERS
WHERE ( DATE BETWEEN '01/01/2012' AND '09/25/2015' )
AND WHERE CUSTOMERID = '23'
However, I get an error when I run this which says:
java.sql.SQLSyntaxErrorException: Syntax error: Encountered "WHERE" at
line 1, column 98.
I know that it is a syntax error in my statement but I'm not sure how it should be written to prevent this from occurring
Leave out the second WHERE
WHERE (DATE BETWEEN '01/01/2012' AND '09/25/2015') AND CUSTOMERID='23'
This version should work; extra where clause, and I'm assuming your customerid is an integer, not a string.
SELECT SUM(COST) AS TotalCost
FROM ORDERS
WHERE (
DATE BETWEEN convert(datetime, '01/01/2012') AND convert(datetime, '09/25/2015')
)
AND CUSTOMERID = 23
Related
I have a table that contains one or more entries for each user by date. The format of the date field is in BIGINT format. I’m able to convert the date into a readable format using “DATEADD(SS, CONVERT(BIGINT, Create_Date__c), '19700101')” however, I also need to retrieve only the most recent date for each user. Everything I’ve found indicates you can’t use the MAX function with a DATEADD function. Is there another command? I’m using SQL Server 17.9.1.
Those dates are unix dates...encoded as the number of seconds since 1/1/1970. You sure don't need to convert them to dates to figure out which are the most recent ones. You can select the most-recent dates and users as keys of a virtual table...and then join that to the original table:
select
dateadd( ss, orig.[date], '19700101' ) as realDate,
--> other stuff you need here...
from
(
select
[user],
max( Create_Date__c ) [date]
from
someTable
group by
[user]
) as recent
inner join
someTable orig
on
recent.[user] = orig.[user]
and
recent.[date] = orig.Create_Date__c
BTW, and if you're wondering, I put the [user] and [date] column names in brackets because they're reserved words.
I need to set a "waived" flag in my table for all but the newest result per id. I thought I had a query that will work here, but when I run a select on the query, I'm getting incorrect results - I saw one case where it selected both of the only two results for a particular id. I'm also getting multiple results with the same exact data.
What am I doing wrong here?
Here's my select statement:
select t.test_row_id, t.test_result_id, t.waived, t.pass, t.comment
from EV.Test_Result
join EV.Test_Result as t on EV.Test_Result.test_row_id = t.test_row_id and EV.Test_Result.start_time < t.start_time and t.device_id = 1219 and t.waived = 0
order by t.test_row_id
Here's the actual query I want to run:
update EV.Test_Result
set waived = 1
from EV.Test_Result
join EV.Test_Result as t on EV.Test_Result.test_row_id = t.test_row_id and EV.Test_Result.start_time < t.start_time and t.device_id = 1219 and t.waived = 0
If I understand this correctly, you are having problems because the Cardinality of the ON predicate returns all matching rows.
EV.Test_Result.test_row_id = t.test_row_id
and EV.Test_Result.start_time < t.start_time
This ON will compare all of the start_time values that have the same id and return every combination of result sets where start_time is lesser than the t.start_time. Clearly, this is not what you want.
and t.device_id = 1219
and t.waived = 0
This is actually a predicate (ON technically is one), but I would prefer to use this in a subquery/CTE for several reasons: You limit the number of rows SQL has to retrieve and compare.
Something like the following might be what you needed:
SELECT A.test_row_id
, A.test_result_id
, A.waived
, A.pass
, A.comment
FROM EV.Test_Result A
INNER JOIN (SELECT MAX(start_time) AS start_time
, test_row_id
FROM EV.Test_Result
WHERE device_id = 1219
AND waived = 0
GROUP BY test_row_id
) AS T ON A.test_row_id = T.test_row_id
AND A.start_time < T.start_time
ORDER BY A.test_row_id
This query then returns a 1:M relationship between the values in the ON predicate, unlike the M:M query you had run.
UPDATE:
Since I sheepishly screwed up trying to alter my Query on SO, I'll redeem myself by explaining the physical and logical orders of basic SQL Query operators:
As you know, you write a simple SELECT statement like the following:
SELECT <aggregate column>, SUM(<non-aggregate column>) AS Cost
FROM <table_name>
WHERE <column> = 'some_value'
GROUP BY <aggregate column>
HAVING SUM(<non-aggregate column>) > some_value
ORDER BY <column>
Note that if you use a aggregate function, all other columns MUST appear in the GROUP BY or another function.
Now, SQL Server requires them to be written in that order although it actually processes this logically by the following order that is worth memorizing:
FROM, WHERE, GROUP BY, HAVING, SELECT, ORDER BY
There are more details found on SELECT - MSDN, but this is why any columns in the SELECT operator must be in the group by or in a aggregate function (SUM, MIN, MAX, etc)...and also why my lazy code failed on your first attempt. :/
Note also that the ORDER BY is last (technically TOP operator occurs after this), and that without it the result is not deterministic unless a function such as DENSE_RANK enforces it (thought this occurs in the SELECT statement).
Hope this helps solve the problem and better yet how SQL works. Cheers
Can you try ROW_NUMBER () function order by timestamp descending and filtering out values having ROW_NUMBER 1 ;
Below query should fetch all records per id except the latest one
I tried below query in Oracle with a table having fields : id,user_id, record_order adn timestamp and it worked :
select
<table_name_alias>.*
from
(
select
id,
user_id,
row_number() over (partition by id order by record_order desc) as record_number
from
<your_table_name>
) <table_name_alias>
where
record_number <>1;
If you are using Teradata DB, you can also try QUALIFY statement. I'm not sure if all DBs support this.
Select
table_name.*
from table_name
QUALIFY row_number() over (partition by id order by record_order desc) <>1;
enter image description hereI am creating a query of two values, a period number and the corresponding date. The periods are accounting periods that are similar but not identical to our months. The dates are largely correct, but there are a few inconsistencies that I thought I would clean up with a WHERE statement.
For example, the date 4/1/2015 belongs in period 3, but it shows up in both period 3 and period 4. To fix this, I thought that I would create a WHERE statement stating:
SELECT DISTINCT table1.period,
table1.datetime
FROM table1
WHERE table1.period <> 4 AND table1.datetime <> '4/1/2015'
This took away all of period 4 away instead of just the one I needed. I have also tried the datetime syntax:
AND table1.datetime <> '20150401 00:00:00.000'
Both syntaxes had the same results. I am fairly inexperienced at SQL and have always hated dealing with datetime values, so any help would be great.
-EDIT- Forgot to add single quotations to the first datetime WHERE clause.
Try following:
SELECT DISTINCT table1.period,
table1.datetime
FROM table1
WHERE CASE WHEN table1.period = 4 AND CONVERT(VARCHAR(8),table1.datetime,112) = '20150401' THEN 1 ELSE 0 END = 0
This only get rid of rows that both has period=4 and datetime=20150401, while your query first get rid of anything that has period=4(no matter what [datetime] is), then get rid of anything has datetime=20150401.
Did you say that period is a string field ? you mean a varchar ?
Also you want to check on the date part only, not the time ?
then you can try this
SELECT DISTINCT table1.period,
table1.datetime
FROM table1
WHERE table1.period <> '4'
AND convert(date, table1.datetime) <> '20150401'
I have a view where I Select about 100 rows to allow users to easily query data. In this data, I have a field that is sometimes a date and sometimes text. A date or text depends on type. I cast to a date value like so.
SELECT Cast(Value as Date) as column
from Table
Where type = 1
When you then try to run a query against this column, you get a Conversion failed when converting date and/or time from character string. Here is the query.
SELECT Column
From View
WHERE Column BETWEEN '01/01/2015' AND '12/31/2015'
I have another field that is a date and if I replace it in this query, the query works. Likewise the data from the whole table will load. Any ideas are appreciated. Thanks
Basically, I need this Query to work and not give me the error described above.
select cast(value as date)
from Value
where type = 1
and cast(value as date) between '01/01/2015' and '12/31/2015'
My guess is that you have entries in that column that cannot be converted to datetime. You may be able to find them by running
Select * from table where isdate(value) = 0
I need to find out the total number of records that were created on a given day.
e.g.
ID CreatedDate
1 17/07/2009
2 12/07/2009
3 17/07/2009
4 05/07/2009
5 12/07/2009
6 17/07/2009
Output:
3 Records were created on 17/07/2009
2 Records were created on 12/07/2009
1 Record was created on 05/07/2009
EDIT
Upon testing the second suggestion made by Chris Roberts of including the formatting in the SQL i get this error:
Syntax error converting the varchar value ' Records were created on ' to a column of data type int.
Does anyone know how to rework the solution so that it works?
You should be able to get the data you're after with the following SQL...
SELECT COUNT(ID), CreatedDate
FROM MyTable
GROUP BY CreatedDate
Or - if you want to do the formatting in the SQL, too...
SELECT CONVERT(varchar, COUNT(ID)) + ' Records were created on ' + CONVERT(varchar, CreatedDate)
FROM MyTable
GROUP BY CreatedDate
Good luck!
Is the column actually a timestamp? In which case you will need to apply a function to remove the time component, e.g.:
SELECT COUNT(*), date(CreatedDate) FROM MyTable GROUP BY date(CreatedDate)
I don't know what the function is in T-SQL, it's date() in MySQL and trunc() in Oracle. You may even have to do a to_string and remove the end of the string and group by that if you lack this.
Hope this helps.
select count(*), CreatedDate from table group by CreatedDate order by count(*) DESC