I have a big Access database I am working on, designed by someone else. I am trying to improve it. The way it was set up, first you run Query 1 which makes Table A. Then, run Query 2, which used Table A among others, and made Table B. Then run Query 3, which uses Table B and makes Table C. Then run Query 4, which uses Table C and makes Table D. The final output we use is Table D.
My improvement here was to change Query 1, Query 2, and Query 3 to Select queries, instead of make table queries, and changing the SQL simply by find and replace (for example, in Query 2, replace all the instances of Table A with Query 1 instead). Query 4 is still a make table query and it makes Table D which I export to Excel later.
My question: Can I just run Query 4? That is, will that automatically run Query 3, which will automatically run Query 2, which will automatically run Query 1? Or, do I need to run Query 1 first, then run Query 2, then run Query 3, then run Query 4?
Perhaps beyond that, can I make Query 4 a Select query also? Then, I wouldn't even run Query 4. Instead, I would just export Query 4 itself to Excel and I'm wondering if that would automatically run Query 4, which would run Query 3, and so on.
Just to be clear: I'm not looking for any SQL tips here. I want to keep it just using Access (which is a front-end for SQL, I know) for now.
Note: I realize that one answer here is, "Why don't you try it?" I have and it seems to work as I think it should. The problem is, I have already run all the queries many times before, so I don't know if that makes everything work for now but maybe it won't work the same way later if I haven't already run the previous queries.
Thanks for any help
As Olivier already mentioned, yes selecting from SELECT queries works as you expect. You can actually test this by creating this function in a module
Function LogQueryCall(ByVal query As String)
Debug.Print query & " " & Now
End Function
an then calling it from your queries e.g.
Query1
SELECT *, LogQueryCall("Query1") FROM Table1 ;
Query2
SELECT *, LogQueryCall("Query2")
FROM Query1
INNER JOIN Table2
ON Query1.Field = table2.Field
Query3
SELECT *, LogQueryCall("Query3") FROM Query2
Then you'll see the results in the Immediate Window
Query1 01/03/2012 5:54:46 PM
Query2 01/03/2012 5:54:46 PM
Query3 01/03/2012 5:54:46 PM
Note the function will only get called once per query not once per row
Another option is to create 1 big query. This would use the contents of each query in the from clause like so.
SELECT *
FROM
(Select * FROM Table1) A
INNER JOIN Table2
ON a.Field = table2.Field
The short answer is, "Yes, you can nest SELECT queries and just export to Excel by just exporting the outer-most query result".
Queries can be used exactly like tables in many situations. The nested queries will execute their own SELECT statement and pass their result to the surrounding query as if it was a table.
If query2 calls query1 and
query3 calls query2 and
qyery4 calls query3
... then the queries will automatically be executed in the order shown below by passing their result to the next query when you execute query4:
table -> query1 -> query2 -> query3 -> query4
I assume that your queries look something like this:
query1: SELECT * FROM table;
query2: SELECT * FROM query1;
query3: SELECT * FROM query2;
query4: SELECT * FROM query3;
Related
I have a history table that I am trying to insert data into. The data in the source table is horizontal i need the data vertical. In order to do this, I run 36 queries. I would like to run 1 query that has 36 select statements in it. I wrote a select query that has a union it it. it runs fine and i get the data. when i take that query and convert it to an insert into query, i get an error at the UNION clause
Anyone run into this?
Save your working union select query as a query.
Then use this query as source in a new append query which will append records to your table.
I am doing query on view with single predicates which gives me the record in 4-7 seconds, but when i try to retrieve the record with same predicate and directly with underlying query from that view it gives me records in less then seconds. I am using MySQL.
I have tried checking the execution plan of both the query and it gives major differences if i have hundreds of thousands of records in tables.
So any clue or idea why performance is better when using query directly?
Following is my view definition
SELECT entity_info.source_entity_info_id AS event_sync_id,
entity_info.source_system_id AS source_system_id,
entity_info.target_system_id AS destination_system_id,
event_sync_info.integrationid AS integration_id,
event_sync_info.source_update_time AS last_updated,
entity_info.source_internal_id AS source_entity_internal_id,
entity_info.source_entity_project AS source_entity_project,
entity_info.target_internal_id AS destination_entity_internal_id,
entity_info.destination_entity_project AS destination_entity_project,
entity_info.source_entity_type AS source_entity_type,
entity_info.destination_entity_type AS destination_entity_type,
event_sync_info.opshub_update_time AS opshub_update_time,
event_sync_info.entity_info_id AS entity_info_id,
entity_info.global_id AS global_id,
entity_info.target_entity_info_id AS target_entity_info_id,
entity_info.source_entity_info_id AS source_entity_info_id,
(
SELECT Count(0) AS count(*)
FROM ohrv_failed_event_view_count failed_event_view
WHERE ((
failed_event_view.integration_id = event_sync_info.integrationid)
AND (
failed_event_view.entityinfo = entity_info.source_entity_info_id))) AS no_of_failures
FROM (ohrv_entity_info entity_info
LEFT JOIN ohmt_eai_event_sync_info event_sync_info
ON ((
entity_info.source_entity_info_id = event_sync_info.entity_info_id)))
WHERE (
entity_info.source_entity_info_id IS NOT NULL)
Query examples
select * from view where integration_id=10
Execution plan of this processes 142668 rows for sub query that is there in this view
select QUERY_OF_VIEW and integration_id=10
Execution plan of this looks good and only required rows are getting processed.
I think the issue is in the following query:
SELECT * FROM view WHERE integration_id = 10;
This forces MySQL to materialize an intermediate table, against which it then has to query again to apply the restriction in the WHERE clause. On the other hand, in the second version:
SELECT (QUERY_OF_VIEW with WHERE integration_id = 10)
MySQL does not have to materialize anything other than the query in the view itself. That is, in your second version MySQL just has to execute the query in the view, without any subsequent subquery.
refereeing to this link of documentation you can see,that its depend on if the MERGE algorithm can used it will , but if its not applicable so new temp table must generated to find the relations of data, also you can see this answer that talking about optimization and when to use view and when you should not .
If the MERGE algorithm cannot be used, a temporary table must be used
instead. MERGE cannot be used if the view contains any of the
following constructs:
Aggregate functions (SUM(), MIN(), MAX(), COUNT(), and so forth)
DISTINCT
GROUP BY
HAVING
LIMIT
UNION or UNION ALL
Subquery in the select list
Refers only to literal values (in this case, there is no underlying
table)
I'm working through an SQL injection tutorial. I don't understand one aspect of an SQL statement which is used determine where the different columns in the table will be displayed on the web page and then used to execute statements. A previous SQL injection statement has been used to determine the number of columns in the table, which is 6. The SQL statement is
SELECT * FROM TableName Where id=12 union all select 1,2,3,4,5,6
I've researched the SELECT and UNION ALL statements and haven't been able to work out what is actually going on. My thinking is that the numbers in the 2nd select statement respresent the column numbers.
The second statement used to get the values from the table is:
SELECT * FROM TableName Where id=12 union all select 1,2,3,4,user(),6
What does the select 1,2,3,4,5,6 and select 1,2,3,4, user(),6 component of the SQL injection query actually do?
They are not column numbers but values. Assuming you can somehow inject the statement you now need something to do with it. The first example counts the columns. theUNION will fail when there are not enough columns. By adding more columns to the UNION eventually the statement will execute. Now you know how many columns there are.
The second one is injecting the user into the return result set. Assuming the result set gets displayed on the screen for some reason, you now have a user name (or service account name) with which to execute more statements on your database, escalate privileges or make service calls.
It's doing something like that. Without knowing more it's hard to know what exactly.
Essentially we are sometimes (?) required to provide a reference to table even if I do not need it. E.g.
Query input must contain atleast one table or query
The question I have is why query q1 SELECT 1 executes just fine and gives me 1 row-1 column resultant table with 1 as the value but query q2 SELECT * FROM q1 produces the aforementioned error?
When I change q1 to SELECT 1 from dummy_table where dummy_table is a dummy table with dummy value, q2 runs fine.
Why q1's internal structure is in any way relevant to q2? q1 on its own works just fine. Does the q2 "unrolls" q1 and then compiles a statement
SELECT * FROM (SELECT 1) (which on its own produces the same error). Can I somehow force Access not to peek into parents' internal structure?
Also why SELECT * FROM (SELECT 1) gives an error and SELECT 1 works fine?
Access will only accept a query without a FROM clause when the "naked" SELECT is used in isolation, not as part of another query.
As you discovered, SELECT 1 is valid when it is the entire statement. But Access complains "Query input must contain at least one table or query" if you attempt to use that "naked" SELECT in another query such as SELECT q.* FROM (SELECT 1) AS q;
Similarly, although SELECT 1 and SELECT 2 are both valid when used alone, attempting to UNION them triggers the same error:
SELECT 1
UNION ALL
SELECT 2
There is no way to circumvent that error. As you also discovered, saving the "naked" SELECT as a named query, and then using the named query in another still triggers the error. It's just a limitation of the Access db engine, and it's been that way with every Access version I've used (>= Access 2000).
We ran into this issue today with error 3067 when trying to add some records to query results using a UNION query.
This doesn't work:
SELECT
UserID, UserName
FROM USERS
UNION SELECT
0, 'Add User...'
But as pointed out in the original question, if you use a valid table name, you can work around the issue.
Simply adjust the code to select a single record (TOP 1) from any table. Here I use MSysObjects because that should always exist and have records.
SELECT
UserID, UserName
FROM USERS
UNION SELECT TOP 1
0, 'Add User...'
FROM MSysObjects
Even though we are technically not using any data from the "dummy" table, it satisfies the compiler requirements for our union query and returns the desired results.
I have a function which return me X rows, where X is user selected parameter. I know I can use SQLCALCFOUND_ROWS in query, but I have to use select foundrows(); immediate after. If use select foundrows() after the main query inside my cfquery tag, only the values of total rows are returned. If I use it in another cfquery, it is possible that there is another query in mysql thread and my results are not available. What would be the better way to handle this.
Ok, so I implemented it by wrapping my queries in a cftransaction. Please NOTE: I have to resort to this method only when my primary query is huge and/or running that as subquery to get total record count is not an option. MySql states that SELECT FOUND_ROWS() should run immediately after the query with SQL_CALC_FOUND_ROWS. If I run it in same cfquery tag, I cannot access data from my primary query. If I run another cfquery there is risk that query connection will be returned to pool. #Leigh mentioned that running both queries within a cftransaction ensures that the connection is retained.
Not the best solution, but much better than running a huge query twice.
<cftransaction>
<cfquery name="qry1" datasource="dsn">
select SQL_CALC_FOUND_ROWS col1,col2 from someTable
some complex joins
where a=b
</cfquery>
<cfquery name="qry2" datasource="dsn">
select FOUND_ROWS() as TotalRows;
</cfquery>
</cftransaction>
This answer depends very much on the complexity and time cost of your query. But in a simple example, you can just build a count into the initial query as a subselect. If you have a table of countries for example, you can do the following to get the top 10 and also the total number
select top 10
country_name
,(select COUNT(*) from country) as total
from
country
You could just do a query of the query object that's returned. Feed the name of the query as the datasource and you can run SQL on it. I believe you should be able to do a select count(*) and count the rows that are returned from the first query.