I need to get daily averages for several tags in my data. I am running into a problem with the following query that I have set up:
SET NOCOUNT ON
DECLARE #StartDate DateTime
SET #StartDate = '20100101 00:00:00.000'
SET NOCOUNT OFF
SELECT TagName, DateTime, avg(Value), avg(vValue)
FROM History
WHERE TagName IN ('BFC_CGA_PE.qAr_Reading', 'BFC_CGA_PE.qBTU_Avg', 'BFC_CGA_PE.qBTU_Calc', 'BFC_CGA_PE.qCH4_Reading', 'BFC_CGA_PE.qCO_Reading', 'BFC_CGA_PE.qCO2_Reading', 'BFC_CGA_PE.qH2_Reading', 'BFC_CGA_PE.qN2_Reading', 'BFC_CGA_PE.qO2_Reading')
AND wwRetrievalMode = 'Cyclic'
AND wwVersion = 'Latest'
AND DateTime >= #StartDate
The error that I receive after my attempt to execute is:
Msg 8120, Level 16, State 1, Line 5
Column 'History.TagName' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.
Could someone help to develop a query to fetch daily average values for my tags?
Try this: (GROUP BY clause added and DateTime column removed from query)
SELECT TagName, /*DateTime,*/ avg(Value), avg(vValue)
FROM History
WHERE TagName IN ('BFC_CGA_PE.qAr_Reading', 'BFC_CGA_PE.qBTU_Avg', 'BFC_CGA_PE.qBTU_Calc', 'BFC_CGA_PE.qCH4_Reading', 'BFC_CGA_PE.qCO_Reading', 'BFC_CGA_PE.qCO2_Reading', 'BFC_CGA_PE.qH2_Reading', 'BFC_CGA_PE.qN2_Reading', 'BFC_CGA_PE.qO2_Reading')
AND wwRetrievalMode = 'Cyclic'
AND wwVersion = 'Latest'
AND DateTime >= #StartDate
GROUP BY TagName
ORDER BY TagName
You just need a group by for TagName. Notice I removed your DateTime column for now. Date time values are likely to be unique and therefore not good candidates for aggregation. Not without some work to isolate a section of the data time value.
Add a GROUP BY clause. Also assuming the DateTime field is storing a date and time, you will want to aggregate by date alone to get daily average as in query below:
SELECT
TagName,
DATEADD(D, 0, DATEDIFF(D, 0, DateTime)),
avg(Value),
avg(vValue)
FROM History
WHERE TagName IN ('BFC_CGA_PE.qAr_Reading', 'BFC_CGA_PE.qBTU_Avg', 'BFC_CGA_PE.qBTU_Calc', 'BFC_CGA_PE.qCH4_Reading', 'BFC_CGA_PE.qCO_Reading', 'BFC_CGA_PE.qCO2_Reading', 'BFC_CGA_PE.qH2_Reading', 'BFC_CGA_PE.qN2_Reading', 'BFC_CGA_PE.qO2_Reading')
AND wwRetrievalMode = 'Cyclic'
AND wwVersion = 'Latest'
AND DateTime >= #StartDate
GROUP BY TagName, DATEADD(D, 0, DATEDIFF(D, 0, DateTime))
Related
I have these two tables named Product_details and Pricing table.
Product_details table:
Pricing table:
I want to update the product_Details table if the start date and end date match with today's date and current time.
So, if the start_Date matches with the current date and time, it will update the product_Details table to offer price or promotional price depending on the id that's the inner query returning.
If the end_Date matches with the current date and time, it will delete the offer price or promotional price depending on the id that's the inner query returning.
The code I wrote is as follows.
-- This code works appropriately, which updates the product_details table and inserts offer/promotional prices if the start_Date matches with today's date and current time.
> UPDATE product_Details
SET price_and_price_Type =
> price_and_price_Type ||
> ( pps.details::jsonb ) FROM (
> select id, price_Details as details
> from pricing
> where to_char(start_date,'YYYY-MM-DD HH24:MI') = to_char(now(),'YYYY-MM-DD HH24:MI')
> group by id, details
> ) as pps where product_Details.id = "pps".id ;
-- this is the code that doesn't work. I wrote to delete the jsonB value, which is the offer or promotional price previously updated depending on the id.
UPDATE product_Details
SET price_and_price_Type = price_and_price_Type -
( pps.details::jsonb )
FROM (
select id, price_Details as details
from pricing
where to_char(end_date,'YYYY-MM-DD HH24:MI') = to_char(now(),'YYYY-MM-DD HH24:MI')
group by id, details
) as pps
where product_Details.id = "pps".id ;
The error raises:
ERROR: operator does not exist: jsonb - jsonb
LINE 2: SET price_and_price_Type = price_and_price_Type -
^
HINT: No operator matches the given name and argument types. You might need to add explicit type casts.
SELECT src_user, CAST(start_time as timestamp) as start_time_ts, start_time, dest_ip, src_ip, count(*) as `count`
FROM mytable
WHERE
start_time like '2022-06%'
AND src_ip = '2.3.4.5'
AND rule_name like '%XASDF%'
group by 1, 2, 3, 4, 5 order by 2 desc)
I'm getting an error with pyspark:
[Cloudera][JDBC](10140) Error converting value to Timestamp.
Now, if I don't order by in the query I can get a good result set with timestamps properly converted, so there's a row somewhere that starts with 2022-06 that is not parsing correctly.
How can I setup my error handling so that it will show me the actual value that is causing the error, rather than telling me what the error is?
Here's the code:
df = spark.read.jdbc(url= 'jdbc:impala://asdf.com/dasafsda', table = select_sql, properties = properties)
df.printSchema()
df.show(truncate=False)
I dont know Impala specific function but lets say your normal date is in format yyyy-mm-dd so you can do length check on it if you suspect 2022-06 is causing problem and then set it to default date for error value and store it in separate column to see its real value
like
SELECT src_user,CASE WHEN LENGTH (start_time) =10 THEN CAST(start_time as timestamp) ELSE CAST("1900-01-01" as timestamp) END as start_time_ts, start_time as start_time_raw,start_time, dest_ip, src_ip, count(*) as `count`
FROM mytable
WHERE
start_time like '2022-06%'
AND src_ip = '2.3.4.5'
AND rule_name like '%XASDF%'
group by 1, 2, 3, 4, 5 order by 2 desc)
after this query just filter 1900-01-01 to see vales in start_time_raw which were not casted
I'm trying to get the latest "date" so the max value of "date" and from the same table I want the max value of "stand" also from the same ID.
I have tons of dates, stands for one ID but i only want to extract the latest.
im trying to save it into a function i dont know yet if thats the best idea. The rest of my query It's made of inner joins.
Datum is of type date.
stand is decimal(18,6)
DECLARE #MAXDATE DATE
DECLARE #MAXSTAND decimal(18,6)
SELECT #MAXDATE = MAX(Datum) FROM [dbo].[1] WHERE ID = ID
SELECT #MAXSTAND = Stand FROM [dbo].[2]WHERE ID = ID
Result I get: #MAXDATE: 2106-10-13
Result I get: #MAXSTAND: 0.000000
Result I want: #MAXDATE: 2018-01-16
result I want: #MAXSTAND: 1098.000000
Assuming SQL Server 2012 or higher, you can use the first_value window function:
SELECT FIRST_VALUE(Stand) OVER(ORDER BY Datum DESC)
FROM TableName
WHERE Id = #Id
This will return the value of Stand where the Datum column has the latest value for the specific Id.
With the data provided, I don't think you need to do something else :
SELECT MAX(Datum), MAX(Stand)
FROM TableName
WHERE ID = #MyId
edit : You want it by ID, you can do this :
SELECT MAX(Datum), MAX(Stand), ID
FROM TableName
GROUP BY ID
So I have a string time column in a table and now I want to change that time to date time type and then query data for selected dates.
Is there a direct way to do so? One way I could think of is
1) add a new column
2) insert values into it with converted date
3) Query using the new column
Here I am stuck with the 2nd step with INSERT so need help with that
ALTER TABLE "nds".”unacast_sample_august_2018"
ADD COLUMN new_date timestamp
-- Need correction in select statement that I don't understand
INSERT INTO "nds".”unacast_sample_august_2018” (new_date)
(SELECT new_date from_iso8601_date(substr(timestamp,1,10))
Could some one help me with correction and if possible a better way of doing it?
Tried other way to do in single step but gives error as Column does not exist new_date
SELECT *
FROM (SELECT from_iso8601_date(substr(timestamp,1,10)) FROM "db_name"."table_name") AS new_date
WHERE new_date > from_iso8601('2018-08-26') limit 10;
AND
SELECT new_date = (SELECT from_iso8601_date(substr(timestamp,1,10)))
FROM "db_name"."table_name"
WHERE new_date > from_iso8601('2018-08-26') limit 10;
Could someone correct these queries?
You don't need those steps, just use USING CAST clause on your ALTER TABLE:
CREATE TABLE foobar (my_timestamp) AS
VALUES ('2018-09-20 00:00:00');
ALTER TABLE foobar
ALTER COLUMN my_timestamp TYPE timestamp USING CAST(my_timestamp AS TIMESTAMP);
If your string timestamps are in a correct format this should be enough.
Solved as follows:
select *
from
(
SELECT from_iso8601_date(substr(timestamp,1,10)) as day,*
FROM "db"."table"
)
WHERE day > date_parse('2018-08-26', '%Y-%m-%d')
limit 10
In my SQL Server database I have the dates stored as char(12) in the following format:
yyyymmddhhmm
I didn't create the definition and I cannot modify it. I always dealt with this string at application level, by using C#.
Now I need to perform a task in TSQL and I need to group by month. Therefore I need to extract the month. Is there any TSQL function available for this task?
In case there is not, is it a good solution to create a stored procedure, getMonth(stringDate) that takes the string and extract the 4th and 5th characters from it? Can I use the clause:
group by getMonth(stringDate)
in my query? Thanks
You can;
SUBSTRING(fld, 5, 2)
Personally I would not create a UDF for something so simple (which is what you would consider rather than an SP) unless you find yourself needing to cast that string to DATETIMEs
You can use the following to get your month, since month is always 2 characters after the 4 character year.
declare #date char(12)
set #date = '201203220906'
select substring(#date, 5, 2)
results: 03
or another way to get it is, then you can group by the results in either query:
declare #date char(12)
set #date = '201203220906'
select Month(cast(left(#date, 8) as datetime))
Assuming
CREATE TABLE #Table(
DateValue char(12),
Value int)
INSERT INTO #Table VALUES ('20120110833', 1)
INSERT INTO #Table VALUES ('20120110833', 2)
INSERT INTO #Table VALUES ('20120110833', 3)
INSERT INTO #Table VALUES ('20120210833', 4)
INSERT INTO #Table VALUES ('20120210833', 5)
You can simply do this:
select
MONTH(CAST(LEFT(DateValue, 8) as datetime)) Month,
SUM(value)
FROM
#Table
GROUP BY
MONTH(CAST(LEFT(DateValue, 8) as datetime))
trim the hour/minute part, cast as datetime and apply MONTH function
For this specific case (date in char type with format yyyymmddhhmm), you can use in your query the next functions:
substring (to extract yyyymmdd),
convert (to get datetime value),
datepart (to get month component)
...then you can group by month (or whatever date component), change datecolumnname and tablename with appropiate values
select datepart(month,convert(datetime,substring(datecolumnname,1,8),112)),
count(datepart(month,convert(datetime,substring(datecolumnname,1,8),112)))
from tablename
group by datepart(month,convert(datetime,substring(datecolumnname,1,8),112))