Can i execute query in iif function - ms-access

I want to know can i run a query in iif function used in ms access database. My case
Select field1,(iif(3<4,'Select * from tbl1','select * from tbl2')) from tblmain
I am facing syntax error when i try to executed query like that whats the problem

What you're trying to achieve isn't clear from your sample query.
You can use IIF functions in Access queries, for example:
SELECT IIF([SomeField]<15, "Smaller than 15", "Greater than!") As Whatever
FROM myTable
You can use subselects in Access as well, for example (example shamelessly stolen from http://allenbrowne.com/subquery-01.html):
SELECT MeterReading.ID, MeterReading.ReadDate, MeterReading.MeterValue,
(SELECT TOP 1 Dupe.MeterValue
FROM MeterReading AS Dupe
WHERE Dupe.AddressID = MeterReading.AddressID
AND Dupe.ReadDate < MeterReading.ReadDate
ORDER BY Dupe.ReadDate DESC, Dupe.ID) AS PriorValue
FROM MeterReading;
Note that the specified subselect query must be guaranteed to return a single record - either by specifying TOP 1 or using an aggregate function - and must link back to the parent query in the WHERE clause.
You can't use an IIF statement the way you're trying to in your question, however, even if your subselect was valid, which it is not.
Two options to suggest, although it is less than clear to me what you're trying to achieve here. First, you might want to consider doing it in VBA instead. Something like:
const query1 As String = "Select * from tbl1"
const query2 As String = "select * from tbl2"
Dim recset as DAO.Recordset
set recset = CurrentDB.OpenRecordset(iif(3<4, query1, query2))
Alternatively, if both tbl1 and tbl2 had the same fields you could do something like this:
SELECT * FROM tbl1 WHERE 3<4
UNION ALL
SELECT * FROM tbl2 WHERE NOT (3<4)
If you replace 3<4 by whatever actual condition you're checking for, you'll only get back records from one or the other or query, never both. However, my suspicion is that if you need to do this, your database may have design issues - I can think of many questionable scenarios where this would be needed, and few valid ones, although I'm sure they exist.

Related

In MySQL select query, checking for a string or checking for true in a where clause?

Consider the following table:
SELECT id, Bill_Freq, Paid_From, Paid_To, Paid_Dt, rev_code FROM psr_20160708091408;
The requirement is to fetch the row which has rev_code populated with the string **SUM**.
I've also noticed that for every row with rev_code populated as **SUM** its Bill_Freq won't be either null or zero.
So I wrote two queries to fetch the row with the lowest id
Query based on string check in where clause:
select
min(id) as head_id,
bill_freq,
Paid_From,
Paid_To,
Paid_Dt
from
`psr_20160708091408` where rev_code = "**SUM**";
Query based on true condition:
select
min(id) as head_id,
bill_freq,
Paid_From,
Paid_To,
Paid_Dt
from
`psr_20160708091408` where bill_freq;
I haven't seen anyone use the second type, would like to know its reliability and circumstance of failure.
If by "second type" you mean a where clause with no explicit condition, then there is a good reason why you do not see it.
The SQL standard -- and most databases -- require explicit conditions in the where. MySQL allows the shorthand that you use but it really means:
where not billing_freq <=> 0
or equivalently:
where billing_freq <> 0 or billing_freq is null
(The <=> is the null-safe comparison operator.
The more important issue with your query is the min(). I presume that you actually want this:
select p.*
from psr_20160708091408 p
where rev_code = '**SUM**'
order by id
limit 1;
Also, you should use single quotes as string delimiters. That is the ANSI standard and there is rarely any reason to use double quotes.
Actually you can use the second type of query, but as your requirement is based on rev_code, it is always good to have condition with rev_code, because of 2 reasons
Bill_Freq having no NUlls or Zeros might be assumption based on current data
Even if it is true, in future, your application logic might change and it might have a scenario having NULL or zero, which will break your logic in future.
So my suggestion is to use first query with Rev_code
Please try to use below query
select
id,
bill_freq,
Paid_From,
Paid_To,
Paid_Dt
from
`psr_20160708091408` where rev_code = "**SUM**" ORDER BY ASC LIMIT 0,1;
Thanks.
The requirement says it itself.
The requirement is to fetch the row which has rev_code populated with
the string '**SUM**'
In the scenario that bill_freq IS NOT NULL and rev_code is populated with
the string '**SUM**' then your logic will obviously fail.
Go for
where rev_code = "**SUM**";

MySQL returns all rows when field=0 from SECOND Select query

This case is similar to: S.O Question; mySQL returns all rows when field=0, and the Accepted answer was a very simple trick, to souround the ZERO with single quotes
FROM:
SELECT * FROM table WHERE email=0
TO:
SELECT * FROM table WHERE email='0'
However, my case is slightly different in that my Query is something like:
SELECT * FROM table WHERE email=(
SELECT my_column_value FROM myTable WHERE my_column_value=0 AND user_id =15 LIMIT 1 )
Which in a sense, becomes like simply saying: SELECT * FROM table WHERE email=0, but now with a Second Query.
PLEASE NOTE: It is a MUST that I use the SECOND QUERY.
When I tried: SELECT * FROM table WHERE email='( SELECT my_column_value FROM myTable WHERE my_column_value=0 LIMIT 1 )' (Notice the Single Quotes on the second query)
MySql SCREAMED Errors near '(.
How can this be achieved
Any Suggestion is highly honored
EDIT1: For a visual perspective of the Query
See the STEN_TB here: http://snag.gy/Rq8dq.jpg
Now, the main aim is to get the sten_h where rawscore_h = 0;
The CURRENT QUERY as a whole.
SELECT sten_h
FROM sten_tb
WHERE rawscore_h = (
SELECT `for_print_stens_rowscore`
FROM `for_print_stens_tb`
WHERE `for_print_stens_student_id` =3
AND `for_print_stens_factor_name` = 'Factor H' )
The result of the Second Query can be any number including ZERO.
Any number from >=1 Works and returns a single corresponding value from sten_h. Only =0 does not Work, it returns all rows
That's the issue.
CORRECT ANSWER OR SOLUTION FOR THIS
Just in case someone ends up in this paradox, the Accepted answer has it all.
SEE STEN_TB: http://snag.gy/Rq8dq.jpg
SEE The desired Query result here: http://snag.gy/wa4yA.jpg
I believe your issue is with implicit datatype conversions. You can make those datatype conversions explicit, to gain control.
(The "trick" with wrapping a literal 0 in single quotes, that makes the literal a string literal, rather than a numeric.)
In the more general case, you can use a CAST or CONVERT function to explicitly specify a datatype conversion. You can use an expression in place of a column name, wherever you need to...
For example, to get the value returned by my_column_value to match the datatype of the email column, assuming email is character type, something like:
... email = (SELECT CONVERT(my_column_value,CHAR(255)) FROM myTable WHERE ...
or, to get the a literal integer value to be a string value:
... FROM myTable WHERE my_column_value = CONVERT(0,CHAR(30)) ...
If email and my_column_value are just indicating true or false then they should almost certainly be both BIT NOT NULL or other two-value type that your schema uses for booleans. (Your ORM may use a particular one.) Casting is frequently a hack made necessary by a poor design.
If it should be a particular user then you shouldn't use LIMIT because tables are unordered and that doesn't return a particular user. Explain in your question what your query is supposed to return including exactly what you mean by "15th".
(Having all those similar columns is bad design: rawscore_a, sten_a, rawscore_b, sten_b,... . Use a table with two columns: rawscore, sten.)

Running a SQL SELECT statement against a MYSQL column of SET type

I'm trying to run a SQL SELECT statement against a column that is of type SET. The table is called myTable and the columns in myTable are called base_props and names. The base_props column is of type SET. The values in base_prop are vb,nt, cnt,poss and loc. So I would like to SELECT entries from the column 'name' where base_props have both the values, vb and poss. The results I'm looking to get may have values other than just vb and poss. So to be clear I would like to select all entries that have the values vb and poss regardless if they have other values as well. I've tried the following SQL queries but I can't get the desired results.
SELECT name from myTable WHERE base_props = 'vb' AND base_props = 'poss'
That query returns an empty result set. I've tried using FIND_IN_SET() and IN() but I couldn't get anywhere with that. I've written SQL statements before but never had to deal with columns that are type SET. Any help is appreciated.
The only thing I can come up with is using the LIKE keyword:
SELECT name FROM myTable WHERE (base_props LIKE '%vb%' AND base_props LIKE '%poss%');
This will make sure both vb and cnt are in the base_props column. Of course you can use cnt, nt and loc in there, or any number of base_props values in the sql, just add more AND statements.
OR as a deleted answer by samitha pointed out, you can use FIND_IN_SET:
SELECT name from myTable WHERE FIND_IN_SET('vb', base_props) AND FIND_IN_SET('poss', base_props);
Comment (by spencer7593): "both of these work, but there is a slight difference. The LIKE operator will actually match any member that includes the search string anywhere in a term; the FIND_IN_SET function will only match an exact member. It's also possible to search for members in set by the order they appear in the SET definition, using the MySQL BITAND operator: for example, to match the 1st and 4th members of the set: WHERE base_props & 1 AND base_props & 8". So for example, if you have 'a' and 'aaa' in your set, then using the LIKE "%a%" method will also return rows containing 'aaa'.
Conclusion: use the FIND_IN_SET solution since it will work for all cases.
FIND_IN_SET return index, Try this
SELECT name from myTable WHERE FIND_IN_SET(base_props, 'vb') > 0 AND
FIND_IN_SET(base_props, 'poss') > 0

MySQL select with subquery having replace

So I have a data with format like ;1;;2; and then I need to use this number in a query so I thought I'd convert it to 1,2 and use that in a IN condition. In my table, the result should return 2 rows but instead it is returning only 1 row.
My query is like this. The subquery return 1,2 with no problem but only 1 row is retrieve.
select *
from wt_lists
where id IN ((select replace (replace(sendto, ';;',','),';','')
from wt_stats where statsid IN (1)))
But when I try it with this. It returns the correct result, which in my case is 2 rows.
select *
from wt_lists
where id IN (1,2)
What am I missing here?
Comma delimited strings need to be explicitly defined in the query in order to be used in the IN clause - there's countless examples on SO where people need to use dynamic SQL to incorporate user submitted comma delimited strings.
That said, I have a solution using the FIND_IN_SET function:
SELECT DISTINCT wl.*
FROM WT_LISTS wl
JOIN (SELECT REPLACE(REPLACE(ws.sendto, ';;',','),';','') AS ids
FROM WT_STATS ws
WHERE ws.statsid = 1) x ON FIND_IN_SET(wl.id, x.ids) > 0
You are replacing the string:
';1;;2;'
To:
'1,2'
So, you SQL query looks like:
select * from wt_lists where id IN ('1,2') from wt_stats where statsid IN (1)
To use IN clause you need select different values in different rows.
I found this store procedure that does exactly what you need.
http://kedar.nitty-witty.com/blog/mysql-stored-procedure-split-delimited-string-into-rows/
I have not tested, but it is the way.
Obs: Like David said in the comments above, parsing the data in your application is a better way to do this.

MySQL: how can i convert a string '1,2,3,4' to a (1,2,3,4) so i'll be able to use it in a 'where X in ()' statement

I ran a query that resulted in the string '1,2,3,4'.
How can I run a second query that treats that string as a list of numbers. So I'll be able to do:
select * from tbl where name not in (1,2,3,4)
I would like an answer in pure MySQL.
Well first of all, this usually means that your database structure is not good; you should normalize your database.
However, you can do what you want, with the FIND_IN_SET function:
SELECT * FROM tbl WHERE NOT FIND_IN_SET(name, '1,2,3,4')
Use FIND_IN_SET:
select * from tbl where FIND_IN_SET(name, '1,2,3,4') = 0
Like the other answer, I would also recommend normalizing your database if at all possible. This query could be slow as it will require a scan of the table. Even if there is an index on name this query won't be able to use it efficiently.