There's an error "Temporal data comparison should have the same data type." - sql

created table as below:
login("admin", "123456")
if(existsDatabase("dfs://compoDB")){
dropDatabase("dfs://compoDB")
}
n = 1000000
ID = rand(100, n)
dates = 2017.08.07T00:00:00.000..2017.08.08T00:00:00.000
date = rand(dates, n)
x = rand(10.0, n)
t = table(ID, date, x)
dbDate = database(, VALUE, 2017.08.07..2017.08.11)
dbID=database(, RANGE, 0 50 100)
db = database("dfs://compoDB", COMPO, [dbDate, dbID])
pt = db.createPartitionedTable(t, `pt, `date`ID)
pt.append!(t)
then executed query as below:
select * from loadTable("dfs://compoDB", "pt") where date between 2017.08.07:2017.08.08
there's an error message:
Temporal data comparison should have the same data type.
why

The type of date in where clause should be the same as that in the table. The correct query statement is as follows:
select * from loadTable("dfs://compoDB", "pt") where date between 2017.08.07T00:00:00.000:2017.08.08T23:59:59.999

Related

SELECT a loop over an Array type. BigQuery

Is there any way to loop over an array column within SELECT clause in Google's BigQuery?. Using pseudo-sql:
-- This is some arbitrary complex logic which can be resume as: sum some product while some accumulator is less than a value
accumulator1 = 0
accumulator2 = 0
user_defined_loop =
FOR (x, y) in array
accumulator1 += x * y
accumulator2 += y
IF accumulator2 <= 5000
CONTINUE
ELSE
BREAK
END IF
RETURN accumulator2
END;
WITH example AS (
SELECT [(1,20), (3,40), (5,60)] as array_type_column
UNION ALL
SELECT [(7,80), (9,100), (5,110)]
UNION ALL
SELECT [(5,7), (30,40), (50,60)]
)
SELECT user_defined_loop(array_type_column)
FROM example
Thanks in advance
Try JavaScrpt UDFs:
CREATE TEMP FUNCTION user_defined_loop(arr ARRAY<STRUCT<x INT64, y INT64>>)
RETURNS INT64
LANGUAGE js
AS """
var accumulator1 = 0
var accumulator2 = 0
for (const item of arr)
{
accumulator1 += parseInt(item.x) * parseInt(item.y)
accumulator2 += parseInt(item.y)
if (accumulator2 > 5000) break
}
return accumulator2;
""";
WITH example AS (
SELECT [(1,20), (3,40), (5,60)] as array_type_column
UNION ALL
SELECT [(7,80), (9,100), (5,110)]
UNION ALL
SELECT [(5,7), (30,40), (50,60)]
)
SELECT user_defined_loop(array_type_column)
FROM example

How to Update with subquery in PostgreSQL

I have a function in MS SQL Server just like this:
UPDATE r
SET
monthly =
(
SELECT SUM(-h.value_ini - h.purchase + h.sold + h.value_fin)
FROM hist_portfolio AS h
WHERE h.comp_id = r.comp_id
AND h.port_id = r.port_id
AND h.exte_id = r.cate_id
AND h.type_id = #type_rel_aux
AND h.hcar_day > #date_month_before
AND h.hcar_day <= #date_base
)
FROM #Month_Table r
WHERE type = 1;
and thats the result (after update):
Seq monthly
2 102471,34
1 -5129,46
3 -29841,23
4 0
But when I execute the same update in a fuction in PostgreSQL, all the rows get the same value:
UPDATE Month_Table
SET variacao_mes_rs = (
SELECT SUM(-h.value_ini - h.purchase + h.sold + h.value_fin)
FROM hist_portfolio AS h
WHERE h.comp_id = r.comp_id
AND h.port_id = r.port_id
AND h.exte_id = r.cate_id
AND h.type_id = v_type_rel_aux
AND h.hcar_day > v_date_month_before
AND h.hcar_day <= v_date_base) FROM Month_Table r WHERE type = 1;
Result (after update), all the same value of Seq 3:]
Seq monthly
1 -29841,23
2 -29841,23
3 -29841,23
4 -29841,23
I don't see the cause of the problem...
Does PostgreSQL have different rules on UPDATE?
Can anyone help me?
Remove the FROM clause from Postgres:
UPDATE Month_Table r
SET variacao_mes_rs = (
SELECT SUM(-h.value_ini - h.purchase + h.sold + h.value_fin)
FROM hist_portfolio AS h
WHERE h.comp_id = r.comp_id
AND h.port_id = r.port_id
AND h.exte_id = r.cate_id
AND h.type_id = v_type_rel_aux
AND h.hcar_day > v_date_month_before
AND h.hcar_day <= v_date_base)
WHERE type = 1;
The FROM clause in an UPDATE behaves differently in the two databases, as you have discovered.

My while loop is running forever by calculating and inserting the records into a table

I have created a while loop to check if my derived value is less than zero then enter into while loop, increment my Period ID to +1, pull the values from that period and run the logic again.
But my T SQL code is running forever with this logic with the 26000 records which is not a huge data.
Below is my code logic
SELECT #lclcurrentperiod = PERIOD_ID,
#snop_item = FGA_ID,
#lclfullfill_center = fulfillment_center,
#lcldepo_wise_sawtd = DEPOT_WISE_SAWTD,
#lclDemandType = DEMAND_TYPE,
#lclDepo_wise_final = DEPOT_WISE_FINAL,
#lcldepo_wise_forecast = DEPOT_WISE_FORECAST
FROM temp_calc (NOLOCK)
WHERE PERIOd_id IN (SELECT MIN(period_id)FROM temp_calc WHERE depot_wise_forecast > 0)
AND FGA_ID = #fga_id
AND fulfillment_center = #lclFulfillmentCenter
AND DEMAND_TYPE = 'TRANSACTIONAL';
SET #net_offset_forecast = #lclDepo_wise_forecast - #forecast_consumed_by_sales;
INSERT INTO NET_OFFSET_FORECAST (PERIOD_ID,
FGA_ID,
FULFILLMENT_CENTER,
DEMAND_TYPE,
LEGACY_SSC,
DEPOT_WISE_FORECAST,
CUM_FORECAST,
DRAFT_NET_FORECAST,
FORECAST_TO_BE_CONSUMED,
NET_OFFSET_FORECAST)
VALUES (#lclCurrentPeriod, #snop_item, #lclfullfill_center, #lclDemandType, #lclLegacySSC, #lclDepo_wise_forecast, #cum_forecast, #draft_net_forecast, #forecast_consumed_by_sales, #net_offset_forecast);
WHILE (#net_offset_forecast < 0)
BEGIN
SET #lclcurrentperiod = #lclcurrentperiod + 1;
SET #forecast_consumed_by_sales = ABS(#net_offset_forecast);
SELECT #lclcurrentperiod = PERIOD_ID,
#fga_id = FGA_ID,
#lclFulfillmentCenter = FULFILLMENT_CENTER,
#lclDepo_wise_forecast = DEPOT_WISE_FORECAST,
#lclDemandType = DEMAND_TYPE
FROM (SELECT *,
ROW_NUMBER() OVER (ORDER BY PERIOD_ID) AS RN
FROM TEMP_CALC
WHERE DEPOT_WISE_FORECAST > 0
AND FGA_ID = #fga_id
AND fulfillment_center = #lclFulfillmentCenter
AND DEMAND_TYPE = 'TRANSACTIONAL') t
WHERE RN = 1;
SET #net_offset_forecast = #lcldepo_wise_forecast - #forecast_consumed_by_sales;
INSERT INTO NET_OFFSET_FORECAST (PERIOD_ID,
FGA_ID,
FULFILLMENT_CENTER,
DEMAND_TYPE,
LEGACY_SSC,
DEPOT_WISE_FORECAST,
CUM_FORECAST,
DRAFT_NET_FORECAST,
FORECAST_TO_BE_CONSUMED,
NET_OFFSET_FORECAST)
VALUES (#lclCurrentPeriod, #snop_item, #lclfullfill_center, #lclDemandType, #lclLegacySSC, #lclDepo_wise_forecast, #cum_forecast, #draft_net_forecast, #forecast_consumed_by_sales, #net_offset_forecast);
END;
After deriving the net offset forecast it is going into while loop when the net offset forecast is less than zero and performing actions there and not coming up out with the data.
Need to improve the performance of the code to finish the loop and continue processing other data.

SQL query in Ruby not finding DateTime in where statement properly

Appointments have two fields, an at (a datetime) and minutes (integer, length of appointment)
appointment_a: at = "2015-04-02 21:00:00", and minutes = 60, which already exists.
I'm trying to create appointment_b, where at = "2015-04-02 21:30:00", and minutes = 60.
This is a validation in the Appointment model:
def check_overlap
from = appointment_a.at
to = appointment_a.minutes * 60 + appointment_a.at
if Appointment.where('at >= ? AND at + minutes * 60 >= ?', from, to).emtpy? == false
errors.add(:at, (" field will cause overlap between existing appointments "))
end
end
Why is this not adding errors?
If you try to add a Time to an Integer you get an error:
Time can't be coerced into Fixnum
Maybe if you change your to variable declaration to this:
to = appointment_a.at + appointment_a.minutes * 60
This way, you're adding an Integer to a Time type, so there should be no errors

Linq: Group by Time Interval

I've the following Datatable:
[Date];[Time];[ProcessID];[ID]
24.09.2012;08:18:00;4000;1
24.09.2012;08:18:00;4000;2
24.09.2012;08:19:00;4001;3
24.09.2012;08:23:00;4002;4
24.09.2012;08:32:00;4003;5
...
As result I would like to have a grouping by a 15-minute Time-Interval to count the ProcessIDĀ“s:
[Interval];[ProcessID Count]
8:15:00 - 8:29:00;3
8:30:00 - 8:45:00;1
How to achieve this goal?
Here's the solution against Linq-to-SQL (on SQL Server) with the DateTime being in a single field (a LINQpad query):
Const BaseDate As Date = #9/24/2012#
Const PeriodMinutes As Integer = 15
Dim p = From t In TestData _
Group By q=CInt(Math.Floor((t.SomeDate - BaseDate).TotalMinutes/PeriodMinutes)) Into Group _
Select s=BaseDate.AddMinutes(q*PeriodMinutes), _
e=BaseDate.AddMinutes((q+1)*PeriodMinutes), _
ids=Aggregate g In Group Select g.ProcessID Distinct Into Count()
p.Dump
Using different types and other "little" adjustments could produce simpler SQL backend code.
For your actual database, you need to adjust the Group By, although it now depends upon what your Time column is converted to through Linq-to-SQL and/or your database's driver.
As it is a TimeSpan the Group By becomes something like:
Group By d=t.[Date], q=CInt(Math.Floor(t.[Time].TotalMinutes/PeriodMinutes)) Into Group _
Select s=d.AddMinutes(q*PeriodMinutes), _
e=d.AddMinutes((q+1)*PeriodMinutes), _
ids=Aggregate g In Group Select g.ProcessID Distinct Into Count()
This should work (however, not tested):
Dim groupedByQuarter =
From r In table
Let day = r.Field(Of Date)("Date").Date
Let time = r.Field(Of TimeSpan)("Time")
Let quarter = time.Add(TimeSpan.FromMinutes((-1) * time.Minutes Mod 15))
Group r By Key = New With {Key .day = day, Key .quarter = quarter} Into TimeGroup = Group
Select New With {
.Interval = String.Format("{0} - {1}",
Key.quarter,
Key.quarter.Add(TimeSpan.FromMinutes(14))),
.ProcessCount = TimeGroup.Select(Function(r) r.Field(Of Int32)("ProcessID")).Distinct().Count()
}