automatic way to write monthly queries without specifying init and end date? - google-analytics

I need to automate the date range of my monthly queries using Legacy SQL language.
With this code, Google Bigquery doesn't storage data tables from start to the end of the month (1st May to 31th May).
FROM TABLE_DATE_RANGE([99999999.ga_sessions_],
DATE_ADD(CURRENT_TIMESTAMP(),-30,'DAY'),
DATE_ADD(CURRENT_TIMESTAMP(),-1,'DAY'))

made this in MSsql (its not pretty but i think you will catch the drift)
select cast('01.'+cast(Month(CURRENT_TIMESTAMP) as nvarchar)+'.'+cast(Year(CURRENT_TIMESTAMP) as nvarchar) as Date) as current_month_InitDate from mytable
select Dateadd(day, -1,cast('01.'+cast((Month(CURRENT_TIMESTAMP)+1) as nvarchar)+'.'+cast(Year(CURRENT_TIMESTAMP) as nvarchar) as Date)) as current_month_EndDate from mytable

Related

SQL in Power Query using ODBC

I have a Table with following Columns:
Account_No, Start_Date, End_Date
I downloaded this table into power query using SQL Select command through ODBC.
Now i want to get sum and count of transactions of all accounts given in the above table from Start_Date to End_Date from another Table. e.g. Transaction_Table. What should i do to get my desired results.
Regards
KAM
You probably don't need Power Query at all at this point.
Assuming your DB server is MS SQL Server 2008 or higher,
WITH t1([Account_No], StartDate, EndDate) As
(
SELECT [Account_No], StartDate = MIN([Start_Date]), EndDate = MAX([End_Date])
FROM Table1
GROUP BY Account_No
)
SELECT
[Account_No]
, Amount = SUM([Field_Transaction_Total])
, [Transaction_Count] = COUNT([Field_Transaction_ID])
FROM [Transaction_Table] t2
INNER JOIN t1 ON t2.[Account_No] = t1.Account_No
AND t2.[Field_Transaction_Date] BETWEEN t1.StartDate AND t1.EndDate
You can also use a copy of a query inside WITH block to get this table with accounts and dates to Excel, if you need it.
If you use another SQL Server, just refactor this code, I hope you've got the idea.
You could use a GROUP BY statement in the SQL you wrote, or you could filter the table based on the Start_Date to the End_Date and then right-click on the column you want to count and choose Group By.
I would start a new Query based on your Transaction_Table. Then I would add a Merge step, joining to your 1st Query on Account_No. Then I would Expand the Start_Date and End_Date from the generated NewColumn.
Next I would Add a Custom Column, and write a formula like this:
= [Transaction_Date] >= [Start_Date] and [Transaction_Date] <= [End_Date]
The resulting column will show TRUE or FALSE. Filter for TRUE.
Finally I would add a Group By step to Sum and Count as required.
I hope I've understood your requirement correctly - it wasn't really clear from your question.

How to generate report from sqlite database in cordova phonegap?

How can I generate daily, Weekly, Monthly reports from sqlite database in cordova phonegap? I can not getting data between two dates.
I am applying query
"SELECT * FROM sales where saledate <=1-1-2015 AND saledate >=1-1-2016"
where saledate column type is DATE.
Maybe with BETWEEN it works better
SELECT *
FROM sales
WHERE saledate BETWEEN '2015-01-01' AND '2016-01-01';
Also, your query is not ok, you are selecting the dates which are not in the interval. Also use 01 for days and months with only one character, and try using this notation (YYYY-MM-DD)

sqlite compound where datetime queries

I have a 'presure' table in an sqlite3 database with a 'timestamp' column filled by datetime('now') by a python program which runs periodically adding line at a time to my table.
I'd like to query the database so as to return all the values just from today.
Easy enough:
select * from presure where timestamp like "2014-07-10 %";
BUT, I don't want to have to modify the query each time I run it, today ,tomorrow or any other day. So what I want is someway to replace the date string and wild card with a sub query that generates todays date like:
select date('now');
but I have been unsuccessful compounding the two queries. What am I missing?
In SQL, strings are concatenated with ||:
SELECT * FROM presure WHERE timestamp LIKE date('now') || '%'

SQL MAX() function is very slow, is there a better method?

I have a SQL database and ASP.NET web application and most of my queries involve the SQL max function.
For example, the below query takes between approx. 36 seconds to execute (when using the profiler) on both the ASP.NET website and the SSMS.
SELECT MAX(CONVERT(FLOAT,ISNULL(Runhrs,Runho))) -
MIN(CONVERT(FLOAT,ISNULL(Runhrs,Runho))) AS ACTUALHOURSRUN
FROM REPORTINGSYSTEM.DBO.HL_LOGS
WHERE ID_LOCATION = #ID_LOCATION AND
CONVERT(VARCHAR,TIME_STAMP,102)
BETWEEN #STARTDATE AND #ENDDATE
The table in question has approx. 5,000,000 records and 45 columns.
What is the best/fastest/most efficient way of executing the query to reduce the execution time?
Thanks in advance...
An index on ID_LOCATION and TIME_STAMP would be a good candidate.
However, as you are converting the TIME_STAMP field to a VARCHAR, this will prevent it from being able to use the index. Instead, rework the query to remove the need to do the CONVERT and instead work with DATETIME values.
e.g.
SELECT MAX(CONVERT(FLOAT,ISNULL(Runhrs,Runho))) - MIN(CONVERT(FLOAT,ISNULL(Runhrs,Runho))) AS ACTUALHOURSRUN
FROM REPORTINGSYSTEM.DBO.HL_LOGS
WHERE ID_LOCATION = #ID_LOCATION AND TIME_STAMP >= #STARTDATE AND TIME_STAMP < #ENDDATE
Ensure #STARTDATE and #ENDDATE are DATETIME parameters also (I'm assuming this is the datatype of the TIME_STAMP column)
I'd also question what datatypes are the Runhrs/Runho columns? If not stored as FLOAT/DECIMAL already, then could they not be as that would appear to be the most suitable datatype?
There are several things that you need to do:
Make sure that the columns that you search are indexed - You need an index on ID_LOCATION and TIME_STAMP (if you have other queries that query by date across locations or by locations across dates, you may consider defining separate indexes; otherwise, a single combined index will work).
Stop converting the timestamp to a string - use the native data type for #STARTDATE and #ENDDATE in your query, or replace the condition with TIME_STAMP between CONVERT(datetime,#STARTDATE) and CONVERT(datetime,#ENDDATE)
These two changes should make your query faster, especially the second one: currently, CONVERT(VARCHAR,TIME_STAMP,102) forces the query optimizer into a full scan on everything that matches your location, or even a full table scan if there is no index on ID_LOCATION. An indexed search should bring the number of records down to acceptable levels.
The final item to take on is CONVERT(FLOAT,ISNULL(Runhrs, Runho)): if the query speed after the first two modifications remains insufficient, change MAX(CONVERT(FLOAT,ISNULL(Runhrs,Runho))) to CONVERT(FLOAT, MAX(ISNULL(Runhrs,Runho))), and do the same change for the MIN. This may or may not work, depending on the types of Runhrs and Runho.
First, store Rhnhrs as a numeric type. Then you don't need to do the conversion.
Second, you'll make this faster by creating an index on hl_logs(id_location, time_stamp). You could also throw Runhrs and Runho as well. With an index on all four columns (in that order), the query will not even need to go to the original data.
To use the index, you need to change the where statement to something like:
time_stamp bewteen #startTimeStamp and #EndTimeStamp
The SQL engine won't use the index if the variable is the argument to a function.
The resulting query should look more like:
select max(coalesce(runhrs, runho)) - min(coalesce(runhrs, runho) as Actual
from REPORTINGSYSTEM.DBO.HL_LOGS
WHERE ID_LOCATION = #ID_LOCATION AND
TIME_STAMP BETWEEN cast(#STARTDATE as datetime) AND cast(#ENDDATE as datetime)
SELECT CONVERT(FLOAT, MAX(Runhrs)), CONVERT(FLOAT, MAX(Runho),
CONVERT(FLOAT, MIN(Runhrs)), CONVERT(FLOAT, MIN(Runho)
FROM REPORTINGSYSTEM.DBO.HL_LOGS
WHERE ID_LOCATION = #ID_LOCATION
AND TIME_STAMP BETWEEN #STARTDATE AND #ENDDATE
Do the subtraction yourself in the code which call the SQL. (That is the .net code.)
You should have an index on ID_LOCATION, TIME_STAMP, Runhrs, Runho. One index with all four fields. Maybe two indexes.
CREATE INDEX REPORTINGSYSTEM.DBO.HL_LOGS ON ID_LOCATION, TIME_STAMP, Runhrs
CREATE INDEX REPORTINGSYSTEM.DBO.HL_LOGS ON ID_LOCATION, TIME_STAMP, Runho
AND CONVERT(VARCHAR,TIME_STAMP,102)
This is NOT the way to do it - it will cause slowness. Do NOT apply unnecessary functions to the DATA - it robs the optimizer of any chance to use indexes on this field. Do it the other way around, convert the #STARTDATE + #ENDDATE into the same data type as the field. (or, think of it this way you are doing ~ 5,000,000 conversions so that you can compare to 2 variables)
[time_stamp] BETWEEN #STARTDATE AND #ENDDATE
Please understand this actually means:
[time_stamp] > = #STARTDATE AND [time_stamp] <= #ENDDATE
i.e. BOTH "boundary" datetimes are INCLUDED, usually it's easier and more accurate to avoid between's inclusive nature and spell it out like this:
[time_stamp] > = #STARTDATE AND [time_stamp] < #ENDDATE (with #enddate
being "next day at 00:00:00:000)
MAX(CONVERT(FLOAT,ISNULL(Runhrs,Runho))) -
MIN(CONVERT(FLOAT,ISNULL(Runhrs,Runho))) AS ACTUALHOURSRUN
wow, This is a lot of function calls! It's not pure MAX()/MIN() that's at issue here.
Suggest you simply look for Max(Runhrs) etc as previously mentioned, THEN do the subtractions.

Insert multiple rows into SQL Server based on start and end dates

I need to insert several rows into a SQL Server database based on Start Date and End Date textboxes.
E.G. tbStartDate.Text = "25/12/2012" and tbEndDate.Text = "29/12/2012" therefore I need to insert individual rows for the following dates:
25/12/2012
26/12/2012
27/12/2012
28/12/2012
29/12/2012
Please can you help me with the necessary T-SQL to achieve this?
As always there are a few ways. Here are some of them:
You can write code in your app that loops through the days and inserts a single record per day. (generally the worst design)
You can call some SQL script to do it all in the database.
You can wrap up your SQL script in a stored procedure and pass in the start and end date and get the stored procedure to do it for you.
You can cross join to a pre existing tally table and use it to generate your records.
If you can provide
-the version of SQL Server that you're using
-what the table looks like
-whether you're using C# or VB
then we can help further as it can be difficult to pass dates into databases. It can be particularly difficult if you do not validate them.
Anyway here is option 3 for you.
CREATE PROC dbo.t_test
#StartDate DATETIME,
#EndDate DATETIME
AS
WHILE #StartDate <= #EndDate
BEGIN
INSERT INTO YourTable(YourDateField) VALUES (#StartDate)
SET #StartDate = DATEADD(d,1,#StartDate)
END
Then you need to call this stored procedure (called dbo.t_test) from ASP.Net and pass in your two date parametes as dates.
Declare #Startdate datetime
Select #Startdate='20121025'
While #Startdate<='20121029'
begin
if not exists(select * from dummy where DATE=#Startdate)
insert into dummy (date) values (#Startdate)
set #Startdate=#Startdate + 1
end;

Resources