mysql in clause use procedure instead subquery - php

I have created a procedure which returns a single column of officeid
call officetree(15);
I need to get list of employee under officeid's return by officetree procedure
select * from master_employee where officeid in ( here i want put my officeids return from procedure)
Is this possible to achieve this if yes what is the syntax for that.
Inside the procedure
Below ofcid is parameter of procedure
select `ofc_id`
from (select * from master_office
order by `ofc_parent_id`, `ofc_id`) master_office,
(select #pv := ofcid) office
where (find_in_set(`ofc_parent_id`, #pv) > 0
and #pv := concat(#pv, ',', `ofc_id`)) or ofc_id=ofcid

No, AFAIK, you can not use a SP as sub query in MySQL.
Ref: Using a stored procedure as subquery
Ref: https://forums.mysql.com/read.php?10,556522,556538#msg-556538
Is it possible to call stored procs in MySQL 5.5 subqueries.
No.
And for a suggestion, use stored procedure as few as possible (my ten-year experience tells me)

I think there is no way to use a stored procedure result like a subquery.
Your alternatives:
Use the statement from the procedure as subquery.
Fetch the IDs from the SP in PHP and execute a second query with the fetched IDs. select * from master_employee where officeid in ( list of previously fetched IDs )
Use a more powerfull design for the tree structure like "materialized path" or "transitive closure table"

Related

How to handle multiple queries in PHP, including multiple TEMPORARY tables

This question is in relation to the answer of [another question][1] that I've posted a year ago.
Basically, I need to translate the answer in PHP and I don't even know where to start. Should I use 6 queries? Should I concatenate every query into 1 query? Should I use mysqli_multi_query?
I just need some advice, tips, and I will do the rest, I will do the research needed on how to achieve this in PHP.
This is the query that works perfectly and that I need to translate in PHP:
-- Query 1
CREATE TEMPORARY TABLE t (
ID INT AUTO_INCREMENT PRIMARY KEY
)
SELECT
w.work_id,
w.name wname,
r.sort_name rsortname,
CONCAT(r.seo_url, '.', r.recording_id) as rurl
FROM
WORK AS w
JOIN recording AS r ON w.work_id = r.work_id
JOIN `release` AS rl ON r.release_id = rl.release_id
WHERE
r.is_performer = 1
AND r.is_video = 0
ORDER BY
w.work_id,
- rl.released_year DESC,
- rl.released_month DESC,
- rl.released_day DESC,
rl.release_id;
-- Query 2
CREATE TEMPORARY TABLE x
SELECT
MIN(ID) AS ID
FROM
t
GROUP BY
work_id;
-- Query 3
SELECT
work_id,
wname,
rurl
FROM
x
JOIN t ON x.ID = t.ID
ORDER BY
rsortname;
-- Query 4, 5
DROP TEMPORARY TABLE t;
DROP TEMPORARY TABLE x;
Should I use 6 queries?
Yes, and if these queries depend on variable from PHP then you should use prepared statements to execute them.
Should I concatenate every query into 1 query?
Definitely not. They are not one query, they are all separate and you should execute them separately.
Should I use mysqli_multi_query?
Never! Forget that this function even exists. It is difficult to use and completely unnecessary. Just use prepared statements or command-line interface in MySQL for administrative tasks.

mssql/php - Looping through resultset and performing new query efficiently - In-Memory Tables?

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.

Stored Procedure SQL Conversion to MySQL

I have this chunk of SQL from a stored procedure and i can convert almost all of it, except for the 'INTO #t1' line which i believe is a temporary table:
SELECT siteid, MIN(Eload) + dbo.GetOffset(siteid, 'Eload', MIN(time)) AS Eload
INTO #t1
FROM calcdata WITH (NOLOCK)
WHERE siteid IN (SELECT siteid FROM community_site WHERE communityid = #communityid)
AND time between #start AND #finish
AND Eload < 1000000
AND Eload <> 0
GROUP BY siteid
What is the MySQL equivalent of the INTO #t1 line?
Thanks
You should use INSERT ... SELECT statement instead of SELECT with INTO.
I think that is
INTO "tablename"
MySQL does not allow to create temporary tables on the fly. You can create temporary table explicitly (see reference), but you are generally better off with simply creating normal table and dropping it after you are done with it. If you were to create it explicitly and fill, you need to know all fields in advance, which could be cumbersome.

sql count() and *

Is this possible in sql :
COUNT(ads.id) AS ads, *
If not, then what to use? I'm using LEFT JOIN, there are two tables: ads and ad, but I'm not using GROUP BY:
SELECT COUNT(ads.id) AS ads_count,
ads.*
FROM ...
It's not working.
It's certainly possible to include a * in the SELECT list alongside other columns, in general. But COUNT() is an aggregate function, and the implication there is that you're grouping by every other column in the resultset, which is probably not true.
Whether or not that query will function may be heavily dependent on which DBMS you're using, which you haven't specified. In MS SQL Server, you must declare all non-aggregate columns in a GROUP BY clause, and * is not a valid member in a GROUP BY clause, hence in SQL Server that's an invalid query.
MySQL seems to have somewhat looser rules around grouping and using aggregate functions, so it's possible that query may be syntactically valid (I don't have a MySQL database handy to test it), but its results would almost certainly be indeterminate...
You could do something like this:
-- test table
declare #T table(name varchar(10), number int)
select *, count(name)
from #T
group by number, name
In MSSQL, if you select * then you would have to list all of the columns in the group by.
Of course the only counts that would be greater then 1 would be for duplicated rows.
This should work:
SELECT COUNT(ads.id) AS ads_count,
ads2.*
FROM table_name ads
JOIN table_name ads2
GROUP BY ads.id
table_name should be your table name.

Pass array into a stored procedure

I am trying to pass an array of values from php to mysql stored procedures as parameter list and how to use the array inside the stored procedure. The query in the procedure has three IN statements in in there so I would like to do IN(#listOfids) where #listOfids is 1,2,3,4 (an imploded array from php).
So I got a workaround which is to concatenate the query and the parameters so the pseudo code is
CREATE PROCEDURE `related_stories`(IN param1 VARCHAR(255), IN param2 VARCHAR(255), IN param3 VARCHAR(255), IN publishDate INT(11), IN tlimit INT(11))
BEGIN
SET #query =CONCAT( '
select s.* from
(
select * from
(
SELECT something where condition IN (',param1,')
) as table1
UNION ALL
select * from
(
SELECT something where condition IN (',param2,')
) as table2
UNION ALL
select * from
(
SELECT something where condition IN (',param3,')
) as table3
) as s
WHERE (s.publish_date < ',publishDate,')
GROUP BY id limit ',tlimit,';');
PREPARE stmtInsert FROM #query;
EXECUTE stmtInsert;
END
param1,param2,param3 are imploded arrays that is passed in via php e.g.('1,2,3,4'). Hope this helps someone
I think the main problem here is that MySQL doesn't support arrays as a data type. You need to form a one-to-many relationship to another table that contains a foreign key back to your main data and the array's data.
I think you have to pass it in as a csv. Mysql is not very friendly with looping and such so your probably best doing it outside anyways. As far as stored procedure languages go I find Mysql really is lacking.

Categories