Postgresl : Loop a list of values to create SELECT with mulitple WHERE clause - postgresql

I have a simple SQL query such as
SELECT * from tableName
WHERE (field = 'value1') OR (field = 'value2') OR (field = 'value3') ...
I am lazy enough to write hardcode write the SQL query like above.
I want to extract value1, value2 , ... in an array ( or any collections)
How to write the query above so that it can loop the list of values ?
# declare array
# loop for each element in the array
SELECT * from tableName WHERE (field = element)
# or even better
# build the WHERE clause with a loop
whereClause = (field = 'value1') OR (field = 'value2') OR (field = 'value3') ...
SELECT * from tableName WHERE whereClause

As a_horse_with_no_name has mentioned you can
Check if the field is in an array
SELECT *
FROM tableName
WHERE field = ANY(ARRAY['value1', 'value2'])
and you can use a language of your choice to fill these values dynamically
or if those values are already in a table you can
SELECT *
FROM tableName
WHERE field IN (SELECT field FROM otherTableName)

Related

Cannot filter And Or for multiple rows

Currently, I have a table (2 columns ColumnName, Value) with data like this:
ColumnName Value
CustomerName Facebook
CompanyName Google
How can I write a query with And / Or condition to satisfy the request:
With And:
CustomerName = 'YAHOO' And CompanyName = 'Google' will return 0 records
With Or:
CustomerName = 'Facebook' Or CompanyName = 'Google' will return 2 records
I have no idea to begin.
Please advise.
Thanks.
You can research EAV data model for reasons why this model may not scale well.
You can query like so:
declare #YourTable table (ColumnName varchar(100), Value varchar(100) primary key (ColumnName, Value));
insert into #YourTable
select 'CustomerName', 'Facebook' union all
select 'CompanyName', 'Google';
--with And...
select *
from #YourTable
where (ColumnName = 'CustomerName' and Value = 'Yahoo') and
(ColumnName = 'CompanyName' and Value = 'Google')
--with Or...
select *
from #YourTable
where (ColumnName = 'CustomerName' and Value = 'Facebook') or
(ColumnName = 'CompanyName' and Value = 'Google')

Change titles of columns in MDX with T-SQL

I created simply query with T-SQL processed OLAP cube like below:
SELECT * FROM OPENQUERY([linkedserver], 'SELECT NON EMPTY { [Measures].[Revenue] } ON COLUMNS,
NON EMPTY { ([Basic].[Name].[Name].ALLMEMBERS ) } ON ROWS
FROM [SummaryCube]');
The result of query is the table. Titles of columns in this table are defaults, ex.:"[Basic].[Names].[Names].[MEMBER_CAPTION]" but I would like to change these titles for ex.: "Names". I cannot change using aliases or I'm using aliases wrong way. Can anyone tell me how can I change name of column?
Instead of your SELECT *, double quote the names of the returned columns:
SELECT "[Basic].[Name].[Name].[MEMBER_CAPTION]" as Names
You need to use double quotes as SQL Server recognises square brackets as identifiers.
I usually do some conversions as well:
SELECT
Names = CONVERT(VARCHAR(100), "[Basic].[Name].[Name].[MEMBER_CAPTION]"),
Revenue = CONVERT(NUMERIC(18,2),CAST("[Measures].[Revenue]" AS FLOAT))
FROM
OPENQUERY
(
[linkedserver],
'SELECT
NON EMPTY { [Measures].[Revenue] } ON COLUMNS,
NON EMPTY { ([Basic].[Name].[Name].ALLMEMBERS ) } ON ROWS
FROM [SummaryCube]'
);
And if you switched to the better olapextensions addin it would be:
DECLARE #Server NVARCHAR(30) = 'SummaryCubeServerName';
DECLARE #Database NVARCHAR(50) = 'SummaryCubeDatabaseName';
DECLARE #MDX NVARCHAR(MAX) = '
SELECT
NON EMPTY { [Measures].[Revenue] } ON COLUMNS,
NON EMPTY { ([Basic].[Name].[Name].ALLMEMBERS ) } ON ROWS
FROM [SummaryCube];
'
CREATE TABLE #Results(
Names VARCHAR(250),
Revenue FLOAT
);
INSERT INTO #Results
EXEC ExecuteOLAP #Server, #Database, #MDX;
SELECT
Names,
Revenue = ISNULL(CONVERT(DECIMAL(28,8),Revenue),0.0),
FROM #Results;

PostgreSQL query by string is filtering even the values where there are nulls.

I've created a table in PostgreSQL 9.5 as shown below and I added some data to it. However, when I try and query data by case insensitive search like !~* it removes even the null value rows. How can I do a query that will return all categories that are null and vegetables but not fruits?
CREATE TABLE temp
(
category character varying,
item character varying
);
INSERT INTO temp VALUES('Fruits', 'apple');
INSERT INTO temp VALUES('FRUITS', 'applE');
INSERT INTO temp(item) VALUES('Apple');
INSERT INTO temp(item) VALUES('BANANA');
INSERT INTO temp VALUES('Vegetables', 'Cabbage');
Query
Select * from temp where category !~* 'fruits'
Output
category item
-------- --------
Vegetables Cabbage
To deal with the null you can use is distinct from:
Select *
from temp
where lower(category) is distinct from 'fruits'
or if you do want the regular expression:
Select *
from temp
where category !~* 'fruits'
or category is null;
alternatively treat null as something else:
Select *
from temp
where coalesce(category, '') !~* 'fruits'

Return a value if select returned null

I need to return a value if select returned null. however I found a solution here by putting a query in a sub-query
SELECT COALESCE((SELECT id FROM tbl WHERE id = 9823474), 4) AS id FROM RDB$DATABASE;
The query above would return Null because the value 9823474 does not exist in the table but I want to return a value in that case (for ex 4) so I found the only solution to use select inside sub query and then COALESCE would work, If I did not do that COALESCE will also return Null.
Is it the only solution ?
No, that is not an only way for example
Select first 1 id from (
Select id FROM tbl WHERE id = 9823474
Union All
Select 4 from rdb$database)
Or you can use anonymous procedure http://firebirdsql.su/doku.php?id=execute_block
EXECUTE BLOCK RETURNS ( id integer )
AS
BEGIN
IF ( EXISTS (SELECT * FROM tbl WHERE id = 9823474) )
THEN id = 9823474;
ELSE id = 4;
SUSPEND;
END
... there always are many methods there

How to filter records for all rows?

I am designing a SQL query to extract all records from a given table. But the trick here is that this logic is based on a numeric database field. So there are 4 choices: 0,1,2,3. If user selects 0,1, or 2, then my query returns rows with the specified value. But if they choose 3, it should return all of the rows. How do I do this in SQL? I know if this was a string, I could do something like:
WHERE = CASE WHEN = 3 THEN '%' ELSE END
But in this case, is an integer. Sounds relatively simple but I'm getting errors.
Try this:
SELECT *
FROM <YOUR_TABLE>
WHERE
(
<YOUR_COLUMN> = #InputValue OR
3 = #InputValue
)
Where #InputValue is the name of parameter sent to the query.
The simplest way is to do this:
select MyColumn
from MyTable
where ( MyValue = #MyParameter or #MyParameter = 3)
If your interested in better optimization, then you can do this, but it is less maintainable:
if (#MyParameter = 3)
select MyColumn
from MyTable
else
select MyColumn
from MyTable
where MyValue = #MyParameter
If I were forced to implement this functionality, then I would probably do this, just to make things clear:
declare #AllRecords nchar(1)
if (#MyParameter = 3)
set #AllRecords = N'Y'
else
set #AllRecords = N'N'
select MyColumn
from MyTable
where (MyValue = #MyParameter or #AllRecords = N'Y')
Hopefully, I won't ever have to implement a system that mixes flags and data value in this way.
UPDATED
Here is a version that should work with your expanded requirements (this requires one of the newer versions of SQL Server, I think):
declare #SelectedLevels table (LevelId int not null primary key)
if #LevelId = 3
insert into #SelectedLevels (LevelId) values (1), (2)
else if #LevelId = 5
insert into #SelectedLevels (LevelId) values (0), (1), (2)
else
insert into #SelectedLevels (LevelId) values (#LevelId)
select mt.MyColumn
from MyTable mt
inner join #SelectedLevels sl on sl.LevelId = MyTable.LevelId
if #Param = 3
begin
select *
from #T
end
else
if #Param = 2
begin
select *
from #T
where id in (0,1)
end
else
begin
select *
from #T
where id = #Param
end