I am using MySql and have a situation which is a lot like a correlated subquery except that the data in the inner query is not in the database - but in a PHP session.
If all the data were in the database, the query would look something like this:
SELECT * FROM tableA WHERE (tableA.valueA && (
SELECT valueB FROM tableB WHERE tableB.id = tableA.id));
My problem is that I have no tableB. Instead I have a PHP array. How can I inject the array into the query? Should I attempt to create a temporary table somewhere? Or perhaps I should be trying to declare the array as a variable?
The information in the PHP array is specific to each user and changes rapidly. Also, there will be lots of queries so performance is a consideration.
See comments from Wrikken above - I have made this a temporary table and it seems to be a fine solution.
Related
I would like to count the number of rows in a statement returned by a query. The only solutions I found were:
sqlsrv_num_rows() This one seems a bit too complicated for such a simple task like this and I read that using this slows down the execution quite a bit
Executing a query with SELECT COUNT This method seems unnecessary, also it slows down the execution and if you already have a statement why bother with another query.
Counting the rows while generating a table As I have to generate a html table from the statemnt I could put a variable in the table generating loop and increment it by one, but this one only works when you already have to loop through the entire statement.
Am I missing some fundamental function and/or knowledge or is there no simpler way?
Any help or guidance is appreciated.
EDIT: The statement returned is only a small portion of the original table so it wouldn't be practical to execute another query for this purpose.
In sql server table rows information is stored in the catalog views and Dynamic Management Views you can use it to find the count
This method will only work for the physical tables. So you can store the records in one temp table and drop it later
SELECT Sum(p.rows)
FROM sys.partitions AS p
INNER JOIN sys.tables AS t
ON p.[object_id] = t.[object_id]
INNER JOIN sys.schemas AS s
ON t.[schema_id] = s.[schema_id]
WHERE p.index_id IN ( 0, 1 ) -- heap or clustered index
AND t.NAME = N'tablename'
AND s.NAME = N'dbo';
For more info check this article
If you don't want to execute another query then use select ##rowcount after the query. It will get the count of rows returned by previous select query
select * from query_you_want_to_find_count
select ##rowcount
I tried to compare two zipcode columns between two tables to see if values were missing in the second one.
I first wanted to do it with mysql, my query was something like
'SELECT code FROM t1 WHERE t1 NOT IN (select code FROM t2)'
But it was really slow so I tried another way :
I made two select, and then compared the results with array_diff().
With mysql : few minutes, and sometimes crash
With PHP : less than 1 second.
Can someone explain these differences ?
Is my SQL query wrong ?
If your main table has 50k rows, using a sub select in your query will result into 1 + 50k executions of selects. One for the first table, and 50k selects, one for each row. The server compares the row with your sub select that is reloaded every time iterating the main table. This is why your sql code takes its time and it also may be a huge memory problem as well.
See serjoschas information about joins to fix it in sql, it should be even faster that your php solution.
Checking which values are missing within a table (compared to another) can easily be done with a LEFT or RIGHT JOIN they are just made for actions like this.. alternatively take a look at this: How to Find Missing Value Between Two Mysql Tables – serjoscha
One solution to:
SELECT code FROM t1
WHERE code NOT IN ( SELECT code FROM t2 )
will be:
SELECT t1.code
FROM t1
LEFT JOIN t2
ON t1.code = t2.code
WHERE t2.code is null
Have a try. Also have a look on indexing as Cyclone suggests:
If you don't have an index you should definitly add one since this will speed up your query. You could add an index like this: ALTER TABLE ADD INDEX code_idx (code) this should be done for both tables. If you then were to execute EXPLAIN for the query you would see something like Using where; Using index; Using join buffer which is good – Cyclone
Indexing speeds up your query. If the table only provides one column, searching an index table with the same content as the source table will be exactly the same and redundant. Otherwise I strongly recommend indexing the code column of t2 which leads to a high increase of performance and less memory consumtion.
I have a table called page and I query this, for instance,
SELECT *
FROM page
and I access the data each row in this table columns like this $item->title;
I want to know if I can select the row of this table and at the same time I can retrieve what name is this table I am selecting? So when I do this,
echo $item->table_name; then I get this - page
is it possible?
You could, of course, do something like this:
SELECT *, 'page' AS table_name FROM page;
Asking what table you obtained a row from doesn't really make a whole lot of sense though. What would you expect the result to be if you had executed a join? What about a union of two queries that select different tables?
Actually, there appears to be a PHP function to give you the table name of your query. I've never used it, so am not sure how it would work in a join or anything, but it appears to do what you wish at the moment.
I am fairly new to MSSQL and have never used In-Memory Tables and am not 100% sure if this is what I need.
I have a result set from a query (which cannot be amended) and I loop through and display each row of data. For one field of the result set I need to perform a query to get the relevant display data for that field. The issue is I may have to potentially call this query 1000's of times within the loop depending on how many rows there are in the result set.
Can anyone advise on ways to do this efficiently? I have heard of In Memory tables and am wondering if this is what I need? If so where do I start? Or do I simply store in an array or something?
Any advice much appreciated.
Declare #Test_Memory_Table Table
(
/* Fields needed for lookup; use same datatypes as schema */
IndexOrPkFieldName Numeric(19,0),
Field1 varchar(255),
Field2 date
)
Insert into #Test_Memory_Table Select t2.Field1 as field1, t1.field2 as Field2, CONVERT(char(10),t3.Field3, 101) as Field3
From Table1 t1
INNER JOIN Table2 t2 on t1.pkId = t2.pkId and isnull(t2.IS_ACTIVE,0) = 1 and ISNULL(t2.TYPE, 0) > 0
INNER JOIN Table3 t3 on t2.pkId = t3.pkId
select * from #Test_Memory_Table
Just test the query in SSMS and look at the plan to see how long it takes to return the memory table query versus querying the table directly. remember that ssms can be faster than production because of hints defaulted in ssms (e.g. arithabort), but may not be set that way when querying through .net client. If your tables are small I would expect the difference to be marginal.
I am joining two tables: customers and queries.
I am getting the full_name from the customers table and the description from the queries table.
I am wondering if it is possible to have the results of an SQL join split into arrays that correspond with the table the data came from? For example:
$STH = $DBH->prepare("SELECT queries.description, customers.full_name FROM queries INNER JOIN customers ON queries.customer_id = customers.id");
$STH->execute();
$queries = $STH->fetchAll();
At the moment, I can access my data like this: $queries[0]['description'] and $queries[0]['full_name']
However, my question is whether there is an easy way to get the data like so: $job[0]['query']['description'] and $job[0]['customer']['full_name'].
Just as teresko mentioned, I can't understand why you'd need that.
I can only imagine you want to see on the PHP code what are the table that contained the information.
Maybe you could do something like SELECT queries.description as queries_description, then your php code would look like $queries['queries_description']. Would it be enough?
You can loop through the results in PHP and convert it to the data structure you want, but you cannot (as far as I know) automatically group the data into arrays based on the source table. A (somewhat messy) alternative, using SQL is to use a multi-query and create a temp table from your original results, then select the results on a per-table basis, like so:
CREATE TEMPORARY TABLE q AS
(SELECT queries.description, customers.full_name FROM queries
INNER JOIN customers
ON queries.customer_id = customers.id
);
SELECT q.description FROM q;
SELECT q.full_name FROM q;
So, in those SELECT statements, you'll have to list all the columns that you want for each result. Then in PHP, you'll have to iterate over each resultset and put the data into arrays (or objects/whatever) as needed. Errr. A fetchAll will still not get you what you want, but a fetchAll on the first non-empty resultset will get you all the rows from queries and the 2nd will get you all the rows from customers