I have been doubting the way I am currently converting ini commands to from SQL where I only want to update something if the account/row exists(or if a field matches/doesn't match a specific value).
The way I am currently doing it is:
Calling a SELECT query
Grabbing the results from the SELECT query
Calling an UPDATE query based on the conditions from the SELECT query.
Is there a way I can do this without making two callbacks?(The plugin that I am working off of utilizes callbacks since it's threaded).
You can combine them together:
UPDATE x WHERE
y = (
SELECT z WHERE n
)
Just replace the variables for your own SQL!
Hope this helps:)
Related
I want to select all those rows in table A where column x's value is present in table B's column y.
I am new to writing SQL queries have have tried using different combinations of SELECT statement, COUNT function and WHERE clause since are a really long time, but was unable to do so.
Is it possible to do this using plain SQL queries or is something complex like procedure needed?
A typical method is exists:
select a.*
from a
where exists (select 1
from b
where b.y = a.x
);
There is a table named STATION.
I want to display half rows of the table.
MYSQL query
SELECT *
FROM STATION
LIMIT (SELECT COUNT(ID) FROM STATION)/2
I tried to perform a query like this but I am getting syntax error.
What is wrong in this query?
How can I perform this query?
One method is to use window functions:
select t.*
from (select t.*,
ntile(2) over (order by id) as tile
from t
) t
where tile = 1;
I have never seen a need of querying exactly half the table.
If you are asking this out of curiosity, that's fair but if there is really a need where you are trying to implement something like this, please revisit the design.
Coming to your question, you can possibly do two things:
Implement a stored procedure and query the count and store in a variable and then pass it on to the actual SELECT query for the LIMIT clause.
From your client code fire 2 different queries - 1 for count and calculate half (non fraction) and then pass it to the limit clause of next select query .
Here is the query I'm trying to execute, and it's supposed to return a table containing data for the pools that are not full (members_nr < members_max).
SELECT id, name,
(
SELECT COUNT(*) FROM pools_entries WHERE pool_id=p.id AND pending=0
) AS members_nr,
members_max, open
FROM pools p
WHERE id IN(1,2,3,4) AND members_nr < members_max;
The problem is MySQL won't recognize members_nr as a field since it's a result from a subquery. Is there a logic solution to this little issue?
Any help will be much appreciated :)
N.B. is correct, you need the having clause. But for the sake of the googler's i'll share a little knowledge.
The WHERE clause is used for restricting the resultset to specific records, it is also used for optimisation. Mysql uses the WHERE clause to identify which index's it can use to speed up the query.
The HAVING clause is executed right at the end of the query. It is used for filtering the recordset. So imagine you have a list of stuff from the database that matches your WHERE clause. You can then use HAVING to filter that list down further on some set conditions.
My basic rule of thumb is: if you need to select based on a column's value, use WHERE, if you need to select based on the value of something which is not a column in the table, use HAVING.
So I have a couple SQL commands that I basically want to make a proc, but while doing this, I'd like to optimize them a little bit more.
The first part of it is this:
select tr_reference_nbr
from cfo_daily_trans_hist
inner join cfo_fas157_valuation on fv_dh_daily_trans_hist_id = dh_daily_trans_hist_id
inner join cfo_tran_quote on tq_tran_quote_id = dh_tq_tran_quote_id
inner join cfo_transaction on tq_tr_transaction_id = tr_transaction_id
inner join cfo_fas157_project_valuation ON fpv_fas157_project_valuation_id = fv_fpv_fas157_project_valuation_id AND fpv_status_bit = 1
group by tr_reference_nbr, fv_dh_daily_trans_hist_id
having count(*)>1
This query returns to me which tr_reference_nbr's exist that have duplicate data in our system, which needs to be removed. After this is run, I run this other query, copying and pasting in the tr_reference_nbr one at a time that the above query gave me:
select
tr_reference_nbr , dh_daily_trans_hist_id ,cfo_fas157_project_valuation.*,
cfo_daily_trans_hist.* ,
cfo_fas157_valuation.*
from cfo_daily_trans_hist
inner join cfo_fas157_valuation on fv_dh_daily_trans_hist_id = dh_daily_trans_hist_id
inner join cfo_tran_quote on tq_tran_quote_id = dh_tq_tran_quote_id
inner join cfo_transaction on tq_tr_transaction_id = tr_transaction_id
iNNER JOIN cfo_fas157_project_valuation ON fpv_fas157_project_valuation_id = fv_fpv_fas157_project_valuation_id
where
tr_reference_nbr in
(
[PASTEDREFERENCENUMBER]
)
and fpv_status_bit = 1
order by dh_val_time_stamp desc
Now this query gives me a bunch of records for that specific tr_reference_nbr. I then have to look through this data and find the rows that have a matching (duplicate) dh_daily_trans_hist_id. Once this is found, I look and make sure that the following columns also match for that row so I know they are true duplicates: fpv_unadjusted_sponsor_charge, fpv_adjusted_sponsor_charge, fpv_unadjusted_counterparty_charge, and fpv_adjusted_counterparty_charge.
If THOSE all match, I then look to yet another column, fv_create_dt, and make sure that there is less then a minute difference between the two timestamps there. If there is, I run yet another query on the row that was stored EARLIER, which looks like this:
begin tran
update cfo_fas157_valuation set fpv_status_bit = 0 where fpv_fas157_project_valuation_id = [IDRECIEVEDFROMTHEOTHERTABLE]
commit
As you can see, this is still a very manual process even though we do have a few queries written, but I'm trying to find a solution to where we can just run one query, and it would basically do EVERYTHING except for the final query. So basically something that would provide to us a few fpv_fas157_project_valuation_id's that need to be updated.
From looking at these queries, do any of you guys see an easy way to combine all this? I've been working on it all day and can't seem to get something to run. I feel like I keep screwing up the joins and stuff.
Thanks!
You can combine these queries in multiple ways:
use temporary tables to store results of queries - suitable for stored procedure
use table variables to store results of queries - suitable for stored procedure
use Common Table Expressions (CTEs) to store results of queries - suitable for single query
Once You have them in separate tables/variables/CTEs You can easily join them.
Then You have to do one more thing, and that is to find difference in datetime in two consecutive rows. There is a trick to do this:
use ROW_NUMBER() to add a column with number of row partitioned by grouping fields (tr_reference_nbr, ... ) ordered by fv_create_dt
do a self join on A.ROW_NUMBER = B.ROW_NUMBER + 1
check the difference between A.fv_create_dt and B.fv_create_dt to filter the rows with difference less than a minute
Just do a good test of your self-join to make sure You filter only rows You need to filter.
If You still have problems with this, don't hesitate to leave a comment.
Interesting note: SQL Server Denali has T-SQL enhancements LEAD and LAG to access subsequent and previous row without self-joins.
I'm trying to build a query with a variable limit. As far as I know I cannot do something like select * from table limit my_variable;, but I've read on the internet about a workaround:
SET SQL_SELECT_LIMIT = variable;
I have to write this syntax before the query I want to apply the LIMIT in. This works fine if I write a SELECT query after that code line, but it does not work if I write the following code instead:
INSERT INTO table
SELECT * FROM table1;
It will insert every record of the table1 in table2, instead of inserting the quantity of records specified in the first code line I wrote in this post.
How can I accomplish this?
Using prepared statements to dynamically compose SQL queries.