build a dynamic string in sql Equal statement - sql

I need something to build a string in an sql equal statement, composed by two part, the first one choosed by me and the second one dynamically generated by a query
select * from table
where param1= 'test' + (select distinct param2 from table2 where ...)
the second select always return only one record of course.
So the where clause should be where param1='test'+param2
I tried concat function but it doesn't seem the correct way; any suggestion?

Oracle uses the ANSI standard || operator for string concatenation. So, use this:
SELECT *
FROM yourTable
WHERE param1 = 'test' || (SELECT DISTINCT param2 FROM table2 WHERE ...);
The CONCAT function should also work here:
SELECT *
FROM yourTable
WHERE param1 = CONCAT('test', (SELECT DISTINCT param2 FROM table2 WHERE ...));

select * from table
where param1= 'test' || (select distinct param2 from table2 where ...)

Related

SQL 'WHERE' retrieve all data from a filter

With this query:
SELECT *
FROM table1
WHERE name = 'Peter'
I can retrieve all data from Peter from table1. This can be done with the "Wildcard *".
Question
Is there any kind of wildcard for the WHERE part? For example:
SELECT *
FROM table1
WHERE name = *
This option of course not working, but I am looking for a wild card there so that all names will be included in my query. I know it's easier to remove the WHERE statement, but due to some reasons I still need it.
SELECT *
FROM table1
WHERE True OR name = 'Peter'
;
This may look silly, but it can come in handy when generating query strings, eg in PHP/PDO:
$query = "SELECT * FROM names
WHERE ($ignore_name OR name = :the_name)
AND ($ignore_address OR address LIKE :the_address)";
, where the $ignore_xxx variables are either True or False, and completely under your control (not user-input!)
select *
from table1
where name = 'Peter' or name = name;
You can query output into your WHERE clause like so:
SELECT *
FROM table1
WHERE [name] IN (SELECT DISTINCT [name]
FROM table1)

finding records which don't have corresponding records with an extension at the end

Id like to find records with (.XX) extension at the end which don't have corresponding records without an extension (.XX) at the end. Id like to use the "exists" or "not exists" solution if possible as I'm puzzled why mine gives no output.
input
col_a
value1.XX
value1
value2.XX
value3
** expected output**
col_a
value2.XX
code
SELECT *
FROM table1 as a
where
right (table1.[col_a],3) = ".XX"
and exists(
select 1 from table1 b where Left(a.[col_a], Len(a.[col_a]) - 3) = b.[col_a]
)
Hmmm. You
select t1.*
from table1 t1
where t1.col_a like '%.XX' and
not exists (select 1
from table1 tt1
where t1.col_a = tt1.col_a || '.XX'
);
Note: You have not specified your database so this uses the ISO/ANSI standard || for string concatenation. You can check your RDBMs's documentation for the correct concatenation technique.

Is it possible to use Informix NVL with two subqueries?

I want to get a parameter. The priority for getting that parameter is that I have to look for it in Table1, but if it doesn't exist there, I have to look for it in Table2. If not, so that parameter is null (this situation should not happen, but, well, there is always an edge case).
I wanted to try something like this:
SELECT NVL(
SELECT paramValue from Table1
where paramName = "paramName" and Id = "id",
SELECT paramValue from Table2
where paramName = "paramName" and Id = "id")
But it gives me a syntax error.
Is there any way of doing something like this?
Enclose the sub-queries in their own set of parentheses, like this:
SELECT NVL((SELECT Atomic_Number FROM Elements WHERE Name = 'Tungsten'),
(SELECT Atomic_Number FROM Elements WHERE Name = 'Helium'))
FROM sysmaster:informix.sysdual;
74
SELECT NVL((SELECT Atomic_Number FROM Elements WHERE Name = 'Wunderkind'),
(SELECT Atomic_Number FROM Elements WHERE Name = 'Helium'))
FROM sysmaster:informix.sysdual;
2
SELECT NVL((SELECT Atomic_Number FROM Elements WHERE Name = 'Wunderkind'),
(SELECT Atomic_Number FROM Elements WHERE Name = 'Helios'))
FROM sysmaster:informix.sysdual;
 
The last query generated a NULL (empty line) as output, which is mimicked by a non-breaking space on the last line.
Granted, I'm not selecting from two tables; that's immaterial to the syntax, and the sub-queries would work on two separate tables as well as on one table.
Tested with Informix 12.10.FC6 and CSDK 4.10.FC6 on Mac OS X 10.11.5.
There's another way:
SELECT * FROM (
SELECT paramValue from Table1
where paramName = "paramName" and Id = "id"
union all
SELECT paramValue from Table2
where paramName = "paramName" and Id = "id"
) x
LIMIT 1
Which is IMHO easier to read.

return a default record from a sql query

I have a sql query that I run against a sql server database eg.
SELECT * FROM MyTable WHERE Id = 2
This may return a number of records or may return none. If it returns none, I would like to alter my sql query to return a default record, is this possible and if so, how? If records are returned, the default record should not be returned. I cannot update the data so will need to alter the sql query for this.
Another way (you would get an empty initial rowset returned);
SELECT * FROM MyTable WHERE Id = 2
IF (##ROWCOUNT = 0)
SELECT ...
SELECT TOP 1 * FROM (
SELECT ID,1 as Flag FROM MyTable WHERE Id = 2
UNION ALL
SELECT 1,2
) qry
ORDER BY qry.Flag ASC
You can have a look to this post. It is similar to what you are asking
Return a value if no rows are found SQL
I hope that it can guide you to the correct path.
if not exists (SELECT top 1 * FROM mytable WHERE id = 2)
select * from mytable where id= 'whatever_the_default_id_is'
else
select * from mytable where id = 2
If you have to return whole rows of data (and not just a single column) and you have to create a single SQL query then do this:
Left join actual table to defaults single-row table
select
coalesce(a.col1, d.col1) as col1,
coalesce(a.col2, d.col2) as col2,
...
from (
-- your defaults record
select
default1 as col1,
default2 as col2,
...) as d
left join actual as a
on ((1 = 1) /* or any actual table "where" conditions */)
The query need to return the same number of fields, so you shouldn't do a SELECT * FROM but a SELECT value FROM if you want to return a default value.
With that in mind
SELECT value FROM MyTable WHERE Id = 2
UNION
SELECT CASE (SELECT count(*) FROM MyTable WHERE Id = 2)
WHEN 0 THEN 'defaultvalue'
END

Want 'Exists' in a Where clause to be used only when passed parameter has a value

I have a Select like the one below in a stored procedure (shortened for brevity). #param is a parameter to the stored procedure which can be NULL.
SELECT name FROM Table1 WHERE EXISTS (select .... from table2 Where param = #param AND ... AND ...) AND ... AND ...
I would like the EXISTS statement (the part in bold) to be used only when #param has a value otherwise ignore it.
I don't want to use dynamic SQL or temporary tables if possible. I am trying to use a CASE statement to work with the EXISTS statement but with not much luck.
Using the OR in the WHERE clause will most likely by horrendously slow, especially if EXISTS.
Other options...
Union: only one will return rows
SELECT name FROM Table1 WHERE EXISTS (select .... from table2 Where param = #param AND ... AND ...) AND ... AND ...
UNION ALL
SELECT name FROM Table1 WHERE #param IS NULL AND ... AND ...
Conditional branch:
IF #param2 IS NULL
SELECT name FROM Table1 WHERE ... AND ...
ELSE
SELECT name FROM Table1 WHERE EXISTS (select .... from table2 Where param = #param AND ... AND ...) AND ... AND ...
WHERE (#Param IS NULL OR EXISTS (SELECT .... ))
Note that this isn't a guarantee - the query optimizer will do what it wants. But is should be smart enough to optimize the exists clause away.