snowflake error in insert from view materialized - snowflake-cloud-data-platform

I use a function avg in view materialized :
create or replace materialized view vue_mat_wifi_mac as
select macadr,
date_trunc('HOUR', time_part) as tranche_heure,
avg(rssi) as rssimoy,
sum(nbcapture) as nbcapture
from ext_iot_wifi_mac
group by macadr, tranche_heure;
and when I insert in another table the results of view
insert into wifi_mac_staging(rssimoy, tranche_heure, macadr, nbcapture)
select RSSIMOY, tranche_heure, macadr, nbcapture
from ext_iot_wifi_mac;`
i have an error:
SQL compilation error: error line 2 at position 7 invalid identifier 'RSSIMOY'
the query select on table ext_iot_wifi_mac does work
Why ?

If the SQL you post is the SQL you are running the problem is you second query is selecting from the wrong table. If all your column tokens are correct you SQL is the same as
create or replace materialized view MAT_VIEW_A as
select MAT_VIEW_A_COL1,
date_trunc('hour', time_part) as MAT_VIEW_A_COL2,
avg(rssi) as MAT_VIEW_A_COL3,
sum(nbcapture) as MAT_VIEW_A_COL4
from TABLE_A
group by MAT_VIEW_A_COL1, MAT_VIEW_A_COL2;
and
insert into TABLE_B(MAT_VIEW_A_COL1, MAT_VIEW_A_COL2, MAT_VIEW_A_COL3, MAT_VIEW_A_COL4)
select MAT_VIEW_A_COL1, MAT_VIEW_A_COL2, MAT_VIEW_A_COL3, MAT_VIEW_A_COL4
from TABLE_A;`
but the TABLE_A does not have the column MAT_VIEW_A_COL1 so it would seem you ment to select from your MAT_VIEW_A thus your SQL should be:
insert into wifi_mac_staging(rssimoy, tranche_heure, macadr, nbcapture)
select RSSIMOY, tranche_heure, macadr, nbcapture
from vue_mat_wifi_mac;`
but it doesn't really make sense to insert into another table, all the values from a materialized view with no extra enrichment or timestamp/snapshot like extra's. As you are paying for the disk space in the materialized view. Maybe cloning it makes more sense (which I have not investigated, thus this is really what you are trying todo).

Related

How To Get Temp Table to Run Multiple Time

I'm using MS SQL Server. I'm currently working on a query for pulling headcount. In this process, I'm creating temp tables, but noticed that I can only run the query once. If I try running it again after making changes, it gives me the 'There is already an object named '#Test1' in the database.'
My SQL looks like this:
SET NOCOUNT ON SET ANSI_WARNINGS OFF
IF OBJECT_ID('Tempdb..#Headcount') IS NOT NULL
Drop Table #Test1
Select Coalesce(Enddate,GETDATE()) as EndDate1,FirstName,LastName,EmployeeID,CostCenter,JobCode, CompanyCode
Into #Test1
from EmployeeDM.dbo.vEmployeeJobReporting EJ
--Group By FirstName,LastName,EmployeeID,CostCenter
Order by 1
IF OBJECT_ID('Tempdb..#Headcount') IS NOT NULL
Drop Table #Final1
Select max(EndDate1) as Date1, FirstName,LastName,EmployeeID,CostCenter,JobCode, CompanyCode
Into #Final1
From #Test1
Group by FirstName,LastName,EmployeeID,CostCenter,JobCode, CompanyCode
Order by 1
SELECT F.CostCenter,F.FirstName,F.LastName, F.Date1, F.CompanyCode, F.JobCode,F.EmployeeID,(t3.Day_of_Month-t2.Day_of_Month+1)*1.0/t4.Day_of_Month as Headcount,
Case
The last Select statement is the start of the non-temp table query. What can I do / write in the code to be able to run multiple times in a row? Also, the error I'm receiving:
Msg 2714, Level 16, State 6, Line 4
There is already an object named '#Test1' in the database.
Thanks!
When you write ...INTO #test1, you are creating the table based on the content of the select statement. You need to either 1) drop the temp tables at the end of your query, 2) check for them existing at the front end and drop if they exist, 3) both.
You are already checking for #headcount, but dropping #final and #test1 at the beginning. I dont see where you are declaring #headcount as a table?

Generate an sql query from multiple tables, then create new table

I have a tricky bit of sql query I need to write. To best explain it, I will post some pictures to show three tables. The first two are tables which already contain data, the last table will be the table I need created using data from the first two:
You can use JOIN for each column you want to get in final table:
SELECT
Width.itemNumber,
Width.itemValue as 'Width',
Height.itemValue as 'Height',
[Type].valueID as 'Type',
Frame.valueID as 'Frame',
Position.valueID as 'Position'
INTO third_table_name
FROM itemMaster_itemValue Width
JOIN itemMaster_itemValue Height ON Width.itemNumber=Height.itemNumber AND Height.itemPropertyID='Height'
JOIN itemMaster_EnumValue 'Type' ON Width.itemNumber=[Type].itemNumber AND [Type].itemPropertyID='Type'
JOIN itemMaster_EnumValue Frame ON Width.itemNumber=Frame.itemNumber AND Frame.itemPropertyID='Frame'
JOIN itemMaster_EnumValue Position ON Width.itemNumber=Position.itemNumber AND Position.itemPropertyID='Position'
WHERE Width.itemPropertyID='Width'
I'm not sure if you actually are wanting to create a table for the third view or just a query (in access) / view (in MS SQL Server). Here is how I would do it:
In MS-Access:
Step 1 (Which can end here if all you need is a way to see the data in this format)
TRANSFORM Max(P.vid) AS MaxOfvid
SELECT P.inum
FROM (SELECT itemNumber as inum, itemPropertyID as ival, itemValue as vid
FROM itemMaster_itemValue
UNION
SELECT Enum.itemNumber AS inum, Enum.itemPropertyID AS ival, Enum.valueID AS vid
FROM itemMaster_EnumValue AS Enum) AS P
GROUP BY P.inum
PIVOT P.ival;
Step 2 (If you need to actually create an additional table)
Select * INTO tableName FROM previousPivotQueryName;
That will get you what you need in Access.
The SQL Server part is a little different and can all be done in one T-SQL Statement dbo.test is the name of the table you will create... If you are creating a table for performance reasons then this statement can be put into a job and run nightly to create the table. The Drop Table line will have to be removed before the first time you run it or it will fail because the table will not exist yet:
Drop Table dbo.Test
Select * INTO dbo.Test FROM (
/*just use the following part if you only need a view*/
SELECT *
FROM (SELECT itemNumber as inum, itemPropertyID as ival, itemValue as vid
FROM dbo.itemMaster_itemValue
UNION
SELECT Enum.itemNumber AS inum, Enum.itemPropertyID AS ival, Enum.valueID AS vid
FROM dbo.itemMaster_EnumValue AS Enum) P
PIVOT (max(vid) FOR ival IN([Width],[Height],[Type],[Frame],[Position])) PV)PVT;
And that should get you what you need in the most efficient way possible without using a bunch of joins. :)

Record count of a view and its corresponding table does not match without any joins in view SQL Server

I have a view as below in sql server:
use database2
Go
CREATE VIEW view1
AS
WITH date_cte(datecol)
AS (select getdate())
Select Col1,
Col2,
,....
,[Select datecol from date_cte]
FROM database1.schema1.TABLE
on top a table in different database.
The record count of table as well as view using statement
Select count(1) from database1.schema1.TABLE -- 15487212
Select count(1) from database2.schema2.view1 -- 13324921
Does this problem have any solution?
First of all... you definitely should improve your code:
USE database2
Go
CREATE VIEW schema2.view1
AS
SELECT Col1,
Col2,
,....
,getdate()
FROM database1.schema1.TABLE
Why do you use a CTE just for the date? Another thing, which may cause your error. You create a view without defining your schema. Maybe your view is created but in a different schema? I've added schema2 to your CREATE due to the fact your querying schema2 at the end.
By the way. Your select can be improved too:
Select count(*) from database1.schema1.TABLE -- ??
Select count(*) from database2.schema2.view1 -- ???
Actually the issue here was that data was loading into source table while I was running query to count records.
Therefore the count difference was prevailing.
Thanks for your input

sql server: cannot replicate same order when creating tables

When I run this code, it gives me different sorting results. When I manually do this in Excel, I always get the same results. Can anyone help? Thanks.
select * into tblVSOELookupSort1 from tblVSOELookup order by
[SKU],[ASP Local],[Sum of Qty]
alter table tblVSOELookupSort1 add RowID int identity(1,1) not null
select * into tblVSOELookupSort2 from tblVSOELookupSort1 order by
[Region Per L/U],[Currency]
drop table tblVSOELookupSort1
drop table tblVSOELookup
exec sp_rename tblVSOELookupSort2, tblVSOELookup
select * from tblVSOELookup
That's normal. SQL databases in general do not guarantee a particular row ordering of results unless you specify one. The order is dependent on the RDBMS implementation, query plan, and other things. If you want a particular row ordering in your query results, you must include an ORDER BY clause in your query. In this case, select * from tblVSOELookup order by ....

Create view across multiple databases

I have two databases; 1 is a live database for daily data input and the other is an archival DB for older data.
How can I create a view which gets data from both databases?
Three tables are involve... database1.dbo.table and database1.dbo.tran1 in same database, and database_archived.dbo.table1:
Create VIEW [dbo].[VW_Table_ALL]
AS
SELECT * FROM database1.dbo.table1
UNION ALL
SELECT * FROM database_archived.dbo.table1 as Data INNER JOIN
database1.dbo.tran1 as Tran ON Data.Tran_id = Tran.Tran_Id
GO
Not sure if you need a UNION or a JOIN, but in either case you can just use a three-part name for the object in the other database:
USE database1;
GO
CREATE VIEW dbo.MyView
AS
SELECT columns FROM dbo.LocalTable
UNION ALL
SELECT columns FROM database2.dbo.RemoteTable;
GO

Resources