I'm trying to query the database as flows:
select count(distinct(TE_ID)) from TE where LAST_UPDATE_TIME >= '2013-01-08-00:00:00.000000' and LAST_UPDATE_TIME < '2013-01-09-00:00:00.000000'
However the error I receive is:
11:25:09 [SELECT - 0 row(s), 0.000 secs] [Error Code: 1100, SQL State: HY000] ERROR: Bad timestamp external representation '2013-01-08-00:00:00.000000'
... 1 statement(s) executed, 0 row(s) affected, exec/fetch time: 0.000/0.000 sec [0 successful, 0 warnings, 1 errors]
The timestamp you are giving has an extra dash.
Yours: select cast('2013-01-08-00:00:00.000000' as timestamp)
Should be: select cast('2013-01-08 00:00:00.000000' as timestamp)
To control it might be a good idea to explicitly cast like the example below:
to_timestamp('2013-01-08 00:00:00.000000','YYYY-MM-DD HH:MI:SS.US')
HH = Hour
MI = Minute
SS = Second
US = Microseconds
Try this:
select count(distinct(TE_ID)) from TE where LAST_UPDATE_TIME >= '2013-01-08 00:00:00.000000' and LAST_UPDATE_TIME < '2013-01-09 00:00:00.000000'
Related
I have the below, which gives me a set in hive
collect_set(quotaname)
Sample output:
["Quota1", "Quota2"]
I have tried to use contains or LIKE operator, but I can't figure out how to say If the last item in the set = X then...
Can anyone advise me?
You can use array_contains:
hive> select array_contains(array("Quota1", "Quota2"),'Quota2');
OK
true
Time taken: 0.144 seconds, Fetched: 1 row(s)
hive> select array_contains(array("Quota1", "Quota2"),'Quota3');
OK
false
Time taken: 0.096 seconds, Fetched: 1 row(s)
For accessing last item in a set, use set[size(set)-1]:
with mydata as (
select array('Quota1', 'Quota2') as myset
)
select case when myset[size(myset)-1] = 'Quota2' then 'Contains!' else 'No' end from mydata ;
Result:
OK
Contains!
Time taken: 3.375 seconds, Fetched: 1 row(s)
You can use LIKE operator: myset[size(myset)-1] LIKE '%Quota%', etc, etc
I'm trying to use sqlite3 to access data in a database based on a value for the datestamp. Please consider the following code:
live_db_conn = sqlite3.connect('/Users/user/Documents/database.db')
time_period = (dt.now() - timedelta(seconds=time)).strftime('%H:%M:%S')
time_period_data = pd.read_sql_query('SELECT * FROM table1 WHERE Datestamp > {}'.format(str(time_period)), live_db_conn)
When I run this code I get the following error:
pandas.io.sql.DatabaseError: Execution failed on sql 'SELECT * FROM table1 WHERE Datestamp > 12:33:33': near ":33": syntax error
I don't understand where this error comes from, because if I run the following code:
df = pd.read_sql_query('SELECT Datestamp FROM table1 LIMIT 10', live_db_conn)
print(df)
I get the following output:
Datestamp
0 10:46:54
1 10:46:59
2 10:47:04
3 10:47:09
4 10:47:14
5 10:47:19
6 10:47:24
7 10:47:29
8 10:47:34
9 10:47:39
So it seems (to me at least) that my sql query is correct. I've tried to do .format(time_period) instead of .format(str(time_period)) but I can't figure out what I'm doing wrong.
Question: How do I select the portion of the data that corresponds to the selected time period?
Edit: It seems that something is going wrong with the minutes in the timestamp. When I ran the code again I got the same error but with a different timestamp:
pandas.io.sql.DatabaseError: Execution failed on sql 'SELECT * FROM table1 WHERE Datestamp > 12:49:10': near ":49": syntax error
So I'd say that the syntax error has something to do with the minutes in the timestamp..
Instead of
time_period_data = pd.read_sql_query('SELECT * FROM table1 WHERE Datestamp > {}'.format(str(time_period)), live_db_conn)
I did:
time_period_data = pd.read_sql_query('SELECT * FROM table1 WHERE Datestamp > "{}"'.format(time_period), live_db_conn)
which solved the problem!
SQL Server 2012, Amazon RDS
This is my simple query
update [dbo].[DeliveryPlan]
set [Amount] = dp.Amount +
case when #useAmountColumn = 1 and dbo.ConvertToInt(bs.Amount) > 0
then dbo.ConvertToInt(bs.Amount)
else #amount
end
from
BaseSpecification bs
join
BaseSpecificationStatusType t on (StatusTypeID = t.StatusTypeID)
join
[DeliveryPlan] dp on (dp.BaseSpecificationID = bs.BaseSpecificationID and dp.ItemID = #itemID)
where
bs.BaseID = 130 and t.IsActive = 1
It can't be finished. If where condition bs.BaseID=130 (update 7000 rows) change for bs.BaseID=3 (update 1000000 rows) it lasts 13 sec.
Statistics are actual, I think
In performance monitor I see 5% processor usage
When I use sp to watch active connections and for this query
tempdb_allocations is 32, tembdb_current - 32, reads - 32 000 000, cpu - 860 000 (query lasts 20 minutes)
What is the problem?
UPDATE: I added non-clustered index for [DeliveryPlan] - by BaseSpecificationID + ItemID and problem is gone. Unfortunately I see this problem every day with different queries. And problem disappears unpredicatedly.
This will perform better and in a different way as the join conditions will narrow down the number of rows in the first go itself, rather than waiting for the where clause to execute. The execution plan will be different for both (with where/ without where).
UPDATE dp
SET Amount = dp.Amount + CASE
WHEN #useAmountColumn = 1
AND dbo.ConvertToInt( bs.Amount ) > 0 THEN dbo.ConvertToInt( bs.Amount )
ELSE #amount
END
FROM BaseSpecification bs
JOIN BaseSpecificationStatusType t ON
( bs.StatusTypeID = t.StatusTypeID
AND bs.BaseID = 130
AND t.IsActive = 1
)
JOIN DeliveryPlan dp ON
( dp.BaseSpecificationID = bs.BaseSpecificationID
AND dp.ItemID = #itemID
);
You may suffer from a locking condition for your base tables.
Optimize your query to update dp directly to avoid update all rows of DeliveryPlan
update dp set [Amount] = dp.Amount +
case
when #useAmountColumn=1 and dbo.ConvertToInt(bs.Amount)>0 then
dbo.ConvertToInt(bs.Amount)
else #amount
end
from
BaseSpecification bs
join BaseSpecificationStatusType t on (bs.StatusTypeID = t.StatusTypeID)
join [DeliveryPlan] dp on (dp.BaseSpecificationID = bs.BaseSpecificationID)
where
bs.BaseID = 130
and t.IsActive = 1
and dp.ItemID = #itemID
If the problem mentioned in the update part is that it comes and goes randomly, it sounds like bad parameter sniffing. When the problem happens you could look into plan cache to check if the query plan looks ok and in case it doesn't, what are the values the plan was created with (you can find them in the leftmost object in the plan) and for example use sp_recompile and see what kind of plan you'll get the next time.
I have reviewed the other replies to this problem, but cannot find the appropriate response to my situation. I am trying to divide "actual hours" by "estimated hours". However, estimated hours can be null (no entry) or zero. Actual hours can be zero. So when I get to the division statement, I can't have estimated hours as null or actual hours as zero. My "coalesce" statements don't appear to be helping. Any advice would be helpful.
SELECT PUV.ProjectName, PUV.[Project ID], PUV.[Project Director], PUV.[Project Owner (Manager)], PUV.[Project Type1], **COALESCE( PUV.[Estimated Hours], 0 ) AS EstHours
,PUV.ProjectStatusDate, PUV.ProjectStartDate, PUV.ProjectBaseline0StartDate, PUV.ProjectActualStartDate, PUV.ProjectStartVariance, PUV.ProjectBaseline0FinishDate
,PUV.ProjectFinishDate, PUV.ProjectFinishVariance, PUV.ProjectActualFinishDate, PUV.ProjectWork, PUV.ProjectBaseline0Work, PUV.ProjectActualWork, PUV.ProjectWorkVariance, PUV.ProjectRemainingWork
,PUV.[Project Phase], PUV.[Hold - Canceled Indicator], CWI.StageName, TB.TB_BASE_NUM, MAX (TB.CREATED_DATE) RecentBaseline
,CASE WHEN PUV.[Estimated Hours] is null then 0 END AS [Estimated%]
,Case When PUV.ProjectActualWork <> 0 THEN cast(COALESCE(PUV.ProjectActualWork,0) as DECIMAL(20,2) )/Cast(COALESCE(PUV.[Estimated Hours],0)as decimal(20,2)) Else 0 End AS [Estimated%]*
--DATEDIFF(day, PUV.ProjectBaseline0FinishDate, PUV.ProjectFinishDate)
FROM MSP_EpmProject_UserView AS PUV
LEFT OUTER JOIN (
SELECT WSI.ProjectUID, WP.PhaseName, WP.PhaseUID, WS.StageName, WS.StageUID
FROM MSP_EpmWorkflowStage AS WS
INNER JOIN MSP_EpmWorkflowPhase AS WP ON WS.PhaseUID = WP.PhaseUID
INNER JOIN MSP_EpmWorkflowStatusInformation AS WSI ON WS.StageUID = WSI.StageUID AND WSI.StageEntryDate IS NOT NULL AND (WSI.StageStatus != 0 AND WSI.StageStatus != 4)
) AS CWI ON PUV.ProjectUID = CWI.ProjectUID
JOIN sps_ppm_IT_Published.dbo.MSP_TASK_BASELINES AS TB ON PUV.ProjectUID = TB.PROJ_UID
WHERE TB.TB_BASE_NUM = 0
GROUP BY PUV.ProjectName, PUV.[Project ID], PUV.[Project Director], PUV.[Project Owner (Manager)], PUV.[Project Type1], PUV.[Estimated Hours]
,PUV.ProjectStatusDate, PUV.ProjectStartDate, PUV.ProjectBaseline0StartDate, PUV.ProjectActualStartDate, PUV.ProjectStartVariance, PUV.ProjectBaseline0FinishDate
,PUV.ProjectFinishDate, PUV.ProjectFinishVariance, PUV.ProjectActualFinishDate, PUV.ProjectWork, PUV.ProjectBaseline0Work, PUV.ProjectActualWork, PUV.ProjectWorkVariance, PUV.ProjectRemainingWork
,PUV.[Project Phase], PUV.[Hold - Canceled Indicator], CWI.StageName, TB.TB_BASE_NUM
ORDER BY PUV.ProjectName
Your title is utterly unrelated to the question and posting a super long, aliased query from your database is not a great way to get help.
Luckily, I was curious enough to see whether "msg-8134-level-16-state-1-line-1" was a secret message from Mars that I checked it out.
Anyway, here's a small example of how to use a CASE statement to avoid division by zero:
SELECT
CASE WHEN example.estimated_hours != 0 AND example.estimated_hours IS NOT NULL
THEN 100 / example.estimated_hours
ELSE 0 END AS ratio
FROM (
SELECT estimated_hours
FROM (
VALUES (0), (1), (NULL), (2), (3))
AS mock_data (estimated_hours))
AS example;
You can just copy/paste that into your SQL terminal and run it to see the output:
ratio
-------
0
100
0
50
33
(5 rows)
I am writing an update statement where I need to update a list of items all at once with incremental dates. The incremental value is user defined. I found an example that is pretty similar to my needs at http://haacked.com/archive/2004/02/28/sql-auto-increment.aspx , but do not know how I would implement it. That example is:
DECLARE #counter int
SET #counter = 0
UPDATE #tmp_Users
SET #counter = counter = #counter + 1
My current statement is:
strSQL.CommandText = "Update tblItem set item_timed_close=convert(datetime, #item_timed_close),item_timed_start=convert(money, case when item_est_lo < 500 then ((convert(int,item_est_lo+25)/50)*50) when item_est_lo < 1000 then ((convert(int,item_est_lo+50)/100)*100) when item_est_lo < 3000 then ((convert(int,item_est_lo+125)/250)*250) when item_est_lo < 5000 then ((convert(int,item_est_lo+250)/500)*500) else ((convert(int,item_est_lo+12.5)/25)*25) end ) Where item_sale_id=#item_sale_id";
strSQL.Parameters.Add(new SqlParameter("#item_timed_close", SqlDbType.VarChar, 100, ParameterDirection.Input, true, 0, 0, "item_timed_close", DataRowVersion.Current, datetime_Var.AddMinutes(minutes_Var += Increments_var)));
strSQL.Parameters.Add(new SqlParameter("#item_sale_id", SqlDbType.VarChar, 100, ParameterDirection.Input, true, 0, 0, "item_sale_id", DataRowVersion.Current, itemSaleId3_Var));
datetime_Var is user defined, and is a DateTime format. minutes_Var equals zero to start with. Increments_var is user defined. I need item_timed_close to increment by whatever the Increments_var is set to.
EDIT
Results I am looking for would be something like this:
User specifies a starting date of 2012-01-08 12:00:00 PM and an increment of 10 seconds. For each row updated, the date would look like:
2012-01-08 12:00:00 PM
2012-01-08 12:00:10 PM
2012-01-08 12:00:20 PM
2012-01-08 12:00:30 PM
2012-01-08 12:00:40 PM
2012-01-08 12:00:50 PM
2012-01-08 12:01:00 PM
2012-01-08 12:01:10 PM
2012-01-08 12:01:20 PM
The first date could even have the incremented value already added to it for all we care, so long as it increments. I could change the initial starting date with that in mind through code.
Update
With Naval's suggestion, I tried a sub query. First, I set all date fields to NULL. Then, I run the following query:
strSQL3.CommandText = "Update tblItem set item_timed_close=DATEADD(minute,((Select count(*) as Count From tblItem Where item_sale_id=#item_sale_id And item_timed_close Is NULL) * #increment),convert(datetime, #item_timed_close)),item_timed_start=convert(money, case when item_est_lo < 500 then ((convert(int,item_est_lo+25)/50)*50) when item_est_lo < 1000 then ((convert(int,item_est_lo+50)/100)*100) when item_est_lo < 3000 then ((convert(int,item_est_lo+125)/250)*250) when item_est_lo < 5000 then ((convert(int,item_est_lo+250)/500)*500) else ((convert(int,item_est_lo+12.5)/25)*25) end ) Where item_sale_id=#item_sale_id";
strSQL3.Parameters.Add(new SqlParameter("#item_timed_close", SqlDbType.VarChar, 100, ParameterDirection.Input, true, 0, 0, "item_timed_close", DataRowVersion.Current, datetime_Var));
strSQL3.Parameters.Add(new SqlParameter("#item_sale_id", SqlDbType.Int, 5, ParameterDirection.Input, true, 0, 0, "item_sale_id", DataRowVersion.Current, itemSaleId3_Var));
strSQL3.Parameters.Add(new SqlParameter("#increment", SqlDbType.Int, 5, ParameterDirection.Input, true, 0, 0, "increment", DataRowVersion.Current, Increments_var));
I was hoping that I could multiply the sub query by the variable passed in, but it didn't work as expected. It seems to multiply the #increment by 1 for every field. I've run the select statement alone and it returns 471. So I know that part works correctly. Do I need to cast Count as an integer or something?
DONE
I finally got it. I should have thought of this initially.... I had to change the counter variable in my update string's regular Set sequence. Here is my working query.
Declare #auto Int
Set #auto = 0
Update tblItem
set item_timed_close = DATEADD(minute, (#auto * #increment), convert(datetime, #item_timed_close))
, item_timed_start = convert(money,
case when item_est_lo < 500 then ((convert(int, item_est_lo+25)/50)*50)
when item_est_lo < 1000 then ((convert(int, item_est_lo+50)/100)*100)
when item_est_lo < 3000 then ((convert(int, item_est_lo+125)/250)*250)
when item_est_lo < 5000 then ((convert(int, item_est_lo+250)/500)*500)
else ((convert(int,item_est_lo+12.5)/25)*25) end )
, #auto = (#auto + 1)
Where item_sale_id=#item_sale_id
So I used the original example I had found, and just took out the last Set #counter part and put that into my update string's set parameters.
strSQL.Parameters.Add( is not the place to do the incrementing logic. According to the sample, try to work that into your update statement. First add another parameter for Increments_Var and use DATEADD in your update statement to add it to your #item_timed_close while at the same time updating #item_timed_close to the new sum. I would suggest starting with something simple that uses the sample and dates instead of integers, then build up from there.
Try This: ... i am writing a query, you convert it to your database format.
Update TableName Set DateD = DateAdd('MI',(ID*10),'01-Jan-2011 00:00:00')
ID column is your identity field (AutoIncrement) ID*10 = multiplying it by 10 to get different datetime.
I think this will work :)
Take Care:)
I finally got it. I should have thought of this initially.... I had to change the counter variable in my update string's regular Set sequence. Here is my working query.
Declare #auto Int Set #auto = 0 Update tblItem set item_timed_close=DATEADD(minute,(#auto * #increment),convert(datetime, #item_timed_close)),item_timed_start=convert(money, case when item_est_lo < 500 then ((convert(int,item_est_lo+25)/50)*50) when item_est_lo < 1000 then ((convert(int,item_est_lo+50)/100)*100) when item_est_lo < 3000 then ((convert(int,item_est_lo+125)/250)*250) when item_est_lo < 5000 then ((convert(int,item_est_lo+250)/500)*500) else ((convert(int,item_est_lo+12.5)/25)*25) end ),#auto = (#auto + 1) Where item_sale_id=#item_sale_id
So I used the original example I had found, and just took out the last Set #counter part and put that into my update string's set parameters.