Converting SQL query result to temp table - sql

I am trying to turn my sql results into a temp table but it keeps on returning the following error:
Expecting As or Id or quoted-ID.
I know the sql result is correct but when I add SELECT * INTO #newtable FROM, the sql query doesn't work. What is wrong?
SELECT *
INTO #newtable
FROM
(
SELECT
Url,Id
FROM Blob
WHERE
Id IN
(
SELECT
BlobId
FROM
XrefBlobProjectMeeting
)
AND Extension NOT IN ('xlsx','xls','avi','jpg','mp4','wmv','png')
AND (RefContentTypeId IN (11,13,14,35))
)

Not sure why you have the nested SELECTs. This is what you're more likely after, as you then don't have to alias your subquery:
SELECT Url,
Id
INTO #newtable
FROM Blob
WHERE Id IN (SELECT BlobId FROM XrefBlobProjectMeeting)
AND Extension NOT IN ('xlsx', 'xls', 'avi', 'jpg', 'mp4', 'wmv', 'png')
AND (RefContentTypeId IN (11, 13, 14, 35));
You'd be ever better off, however, changing the IN to an EXISTS as well though:
SELECT [Url],
Id
INTO #newtable
FROM Blob B
WHERE EXISTS (SELECT 1
FROM XrefBlobProjectMeeting E
WHERE E.BlobID = B.ID)
AND Extension NOT IN ('xlsx', 'xls', 'avi', 'jpg', 'mp4', 'wmv', 'png')
AND RefContentTypeId IN (11, 13, 14, 35);

I have tried your problem in your way only and it is working for me. Solution is like given below;
SELECT Url,Id
INTO #newtable
FROM Blob
WHERE
Id IN
(
SELECT
BlobId
FROM
XrefBlobProjectMeeting
)
AND Extension NOT IN ('xlsx','xls','avi','jpg','mp4','wmv','png')
AND (RefContentTypeId IN (11,13,14,35))

Related

How to insert query result into existing table in Google's BigQuery using SQL statement?

I have a huge_query_that_runs_fine_alone that starts with select.
I want to insert that query result into existing table, but usual SQL statements no work.
I tried: insert into test_ds.test_tbl (field1, …, fieldN) values (huge_query_that_runs_fine_alone), but query editor says me that select keyword in unexpected place;
And this: select * into test_ds.test_tbl from (huge_query_that_runs_fine_alone), but query editor says me this Syntax error: Unexpected keyword INTO at [1:10];
What to do?
P.S. Full query...
insert into test_bq_dataset.test_tbl (Naimenovanie_SKU, Naimenovanie_TT, MonthNo, YearNo, AmountPromo, SumPromo, AmountNoPromo, SumNoPromo) values (select promos.Naimenovanie_SKU, promos.Naimenovanie_TT, promos.MonthNo, promos.YearNo, AmountPromo, SumPromo, AmountNoPromo, SumNoPromo from
(select Naimenovanie_SKU, Naimenovanie_TT, MonthNo, YearNo, sum(Prodazhi_Litry) as AmountPromo, sum(Prodazhi_Summa_s_NDS) as SumPromo from IACloud0539_Calc.Data2_PROMO where Promo = false group by Naimenovanie_SKU, Naimenovanie_TT, MonthNo, YearNo) promos
left join
(select Naimenovanie_SKU, Naimenovanie_TT, MonthNo, YearNo, sum(Prodazhi_Litry) as AmountNoPromo, sum(Prodazhi_Summa_s_NDS) as SumNoPromo from IACloud0539_Calc.Data2_PROMO where Promo = true group by Naimenovanie_SKU, Naimenovanie_TT, MonthNo, YearNo) nopromos
on
promos.Naimenovanie_SKU = nopromos.Naimenovanie_SKU
and
promos.Naimenovanie_TT = nopromos.Naimenovanie_TT
and
promos.MonthNo = nopromos.MonthNo
and
promos.YearNo = nopromos.YearNo);
Syntax error: Unexpected keyword SELECT at [1:149]
You could just place a SELECT query below the INSERT clause and it'll work just fine
ex:
CREATE TABLE temp.mytest5 (col1 STRING, col2 STRING);
And the insertion:
INSERT INTO temp.mytest5 (col1, col2)
SELECT 'record1', 'record2'

Recursive CTE in H2: No data returned

I am trying to convert a proprietary Oracle CONNECT BY query into a standard SQL query that will run on H2, and generate the same data in the same order.
This is the Oracle query, which works:
SELECT id, name, parent
FROM myschema.mytable
START WITH id = 1
CONNECT BY PRIOR id = parent
This is what I've come up - however, it returns no rows in the ResultSet.
WITH RECURSIVE T(id, name, parent, path) AS (
SELECT id, name, '' AS parent, id AS path
FROM myschema.mytable WHERE id = 1
UNION ALL
SELECT ou.id, ou.name, ou.parent,
(T.path + '.' + CAST (ou.id AS VARCHAR)) AS path
FROM T INNER JOIN myschema.mytable AS ou ON T.id = ou.parent
) SELECT id, name, parent FROM T ORDER BY path
The initial row, and the related rows, both exist in the table.
I am not using H2's Oracle compatibility mode (which doesn't support CONNECT BY, by the way).
The following works for me, for both H2 as well as PostgreSQL (this you can test online using the SQL Fiddle). I had to make a few changes and assumptions (see below):
create table mytable(id int, name varchar(255), parent int);
insert into mytable values(1, 'root', null), (2, 'first', 1),
(3, 'second', 1), (4, '2b', 3);
WITH RECURSIVE T(id, name, parent, path) AS (
SELECT id, name, 0 AS parent,
cast(id as varchar) AS path
FROM mytable WHERE id = 1
UNION ALL
SELECT ou.id, ou.name, ou.parent,
(T.path || '.' || CAST (ou.id AS VARCHAR)) AS path
FROM T INNER JOIN mytable AS ou ON T.id = ou.parent
) SELECT id, name, parent, path FROM T ORDER BY path
Changes:
I assumed id and parent are integers. Because of that, I had to use cast(id as varchar) in the first select.
I replace + with || when concatenating strings.
I used 0 AS parent.
This seems to have been a problem with either the Anorm database access library or the JDBC driver not substituting a query parameter correctly (the query substitution was not shown in the question, because I assumed it wasn't relevant).

How to create an empty anonymous table in Postgres?

In Postgres if I want to create an "anonymous table" (i.e. a temporary query based on data not in the database) I can use VALUES, for example:
select * from (values (1, 'Hello world'), (100, 'Another row')) as foo (mycol1, mycol2);
But how can I create an anonymous table with no rows? (This is for a code generator, so the question isn't quite as odd as it sounds!). The following does not work
select * from (values ) as foo (mycol1, mycol2);
because I get
ERROR: syntax error at or near ")"
LINE 1: select * from (values ) as foo (mycol1, mycol2);
^
I know a work around
select * from (values (NULL, NULL)) as foo (mycol1, mycol2) where mycol1 is not NULL;
but is there a better or "more official" way?
(I would also be interested to know if it is possible to create a table with no columns!)
I think you can do something like this:
select null::text as a, null::int as b
limit 0
SELECT *
FROM generate_series(0, -1)

How to add results of a SELECT to a table

I have a SQL select statement which is comparing two tables. I am getting the values where the rows are the same. Now I have got this in the procedure I need to add these into a new table (coftReconciliationMatches). The table has all the same columns but one additional one 'MatchOrNoMatch'. I need to pass through the values of the row that are matched and also need to pass through 'Match' to the column 'MatchOrNoMatch'
This is the current part of the SQL script I have;
SELECT *
FROM dbo.coftReconciliationFileInfo AS a
WHERE EXISTS (SELECT *
FROM dbo.coftPreReconciliationInfo AS b
WHERE a.Rec_PK = b.Rec_PK
AND a.ExtRef1 = b.ExtRef1
AND a.SedolRef = b.SedolRef
AND a.ValLatest = b.ValLatest
AND a.Totunits = b.Totunits
AND a.FundsOrCash = b.FundsOrCash )
When comparing a lot of columns, the SELECT INTERSECT and SELECT EXCEPT commands can save you a lot of effort:
INSERT dbo.coftReconcilliationMatches
(Rec_PK, ExtRef1, SedolRef, ValLatest, Totunits, FundsOrCash, MatchOrNoMatch)
select Rec_PK, ExtRef1, SedolRef, ValLatest, Totunits, FundsOrCash, 'Match'
from dbo.coftReconciliationFileInfo
intersect select Rec_PK, ExtRef1, SedolRef, ValLatest, Totunits, FundsOrCash, 'Match'
from dbo.coftPreReconciliationFileInfo
(Check for typos!)
If you are creating the table on the fly (something I wouldn't recommend doing), you'd use SELECT INTO.
INSERT INTO [table] ([col1], [col2]) SELECT colx, ...
Use Select Into for this. See here http://www.w3schools.com/sql/sql_select_into.asp
Try something like:
INSERT INTO <your table> (<list of columns>)
SELECT <list of columns from select>, '<the additional column>' FROM dbo.coftReconciliationFileInfo AS a
WHERE EXISTS(SELECT * FROM dbo.coftPreReconciliationInfo AS b
WHERE a.Rec_PK = b.Rec_PK AND a.ExtRef1 = b.ExtRef1 AND a.SedolRef = b.SedolRef AND a.ValLatest = b.ValLatest AND a.Totunits = b.Totunits AND a.FundsOrCash = b.FundsOrCash )
also see http://www.1keydata.com/sql/sqlinsert.html
you need to do:
INSERT INTO Table (column1, column2..)
(SELECT column1, column2 ....
FROM dbo.coftReconciliationFileInfo AS a
WHERE EXISTS (SELECT *
FROM dbo.coftPreReconciliationInfo AS b
WHERE a.Rec_PK = b.Rec_PK
AND a.ExtRef1 = b.ExtRef1
AND a.SedolRef = b.SedolRef
AND a.ValLatest = b.ValLatest
AND a.Totunits = b.Totunits
AND a.FundsOrCash = b.FundsOrCash ))

Using tuples in SQL "IN" clause

I have a table containing the fields group_id and group_type and I want to query the table for all the records having any tuple (group id, group type) from a list of tuples. For example, I want to be able to do something like:
SELECT *
FROM mytable
WHERE (group_id, group_type) IN (("1234-567", 2), ("4321-765", 3), ("1111-222", 5))
A very similar question is already asked at: using tuples in sql in clause , but the solution proposed there presumes the tuple list is to be fetched from another table. This doesn't work in my case is the tuple values are hard coded.
One solution is to use string concatenation:
SELECT *
FROM mytable
WHERE group_id + STR(group_type, 1) IN ("1234-5672", "4321-7653", "1111-2225")
But the problem is that the table is quite big and doing a string concatenation and conversion for each record would be very expensive.
Any suggestion?
Given a very minor tweak (replace double quotes with single and add the VALUES keyword), your proposed syntax is valid Standard SQL-92 syntax i.e.
SELECT *
FROM mytable
WHERE (group_id, group_type) IN (
VALUES ('1234-567', 2),
('4321-765', 3),
('1111-222', 5)
);
Sadly, MSFT have not added it to SQL Server and consider it an 'unplanned' feature.
FWIW PostgreSQL and Sqlite are examples of SQL products that support this syntax.
In SQL Server 2008 you can do like this:
select *
from mytable as T
where exists (select *
from (values ('1234-567', 2),
('4321-765', 3),
('1111-222', 5)) as V(group_id, group_type)
where T.group_id = V.group_id and
T.group_type = V.group_type
)
EDIT: this is a dated answer, although it was the accepted answer in 2011, other answers with more upvotes reflect more recent approaches.
Why not construct the OR statements?
SELECT *
FROM mytable
WHERE (group_id = '1234-567' and group_type = 2)
OR (group_id = '4321-765' and group_type = 3)
OR (group_id = '1111-222' and group_type = 5)
Granted, it doesn't look as nice and neat as your concept example but it will do the job (and if you IN with tuples did exist, it would implement it exactly the same way under the covers most likely.
You can use a common table expression to pretend that these tuples are in another table:
;WITH Tuples as (
select '1234-567' as group_id, 2 as group_type union all
select '4321-765', 3 union all
select '1111-222', 5
)
SELECT * /* TODO - Pick appropriate columns */
from mytable m where exists (
select * from Tuples t
where m.group_id = t.group_id and m.group_type = t.group_type)
Using that solution, this should work:
SELECT *
FROM mytable m
WHERE EXISTS (
SELECT * FROM (
SELECT "1234-567" group_id, 2 group_type UNION ALL
SELECT "4321-765", 3 UNION ALL
SELECT "1111-222", 5) [t]
WHERE m.group_id = t.group_id AND m.group_type = t.group_type)
BTW, you should probably use a CTE to create that inner table.
I haven't seen this yet, but something like this should work
SELECT * FROM AgeGroup ag JOIN
(VALUES
('18-24', 18, 24),
('25-34 ', 25, 39),
('35-44 ', 35, 49),
('45-54 ', 45, 59),
('55-64 ', 55, 69),
('65+ ', 65, 299)
) AS x (agegroup, minage, maxage)
ON ag.age_group = x.agegroup
AND ag.min_age=x.minage
AND ag.max_age=x.maxage
Here is another tuple solution using a join:
SELECT
*
FROM mytable m
JOIN
(
SELECT "1234-567" group_id, 2 group_type
UNION ALL SELECT "4321-765", 3
UNION ALL SELECT "1111-222", 5
) [t]
ON m.group_id = t.group_id
AND m.group_type = t.group_type
I had a similar problem but my tuple collection was dynamic - it was sent over to the SQL Server in a query parameter. I came up with the following solution:
Pass a tuple as an XML:
DECLARE #tuplesXml xml = '<tuples><tuple group-id="1234-567" group-type="2"/><tuple group-id="4321-765" group-type="3"/></tuples>';
Inner join the table that you want to filter with the XML nodes:
SELECT t.* FROM mytable t
INNER JOIN #tuplesXml.nodes('/tuples/tuple') AS tuple(col)
ON tuple.col.value('./#group-id', 'varchar(255)') = t.group_id
AND tuple.col.value('./#group-type', 'integer') = t.group_type
It seems to work fine in my situation which is a bit more complex than the one described in the question.
Keep in mind that it is necessary to use t.* instead of * and the table returned from nodes method needs to be aliased (it's tuple(col) in this case).
select * from table_name where 1=1 and (column_a, column_b) in ((28,1),(25,1))