How to select multiple rows based on AND condition on a column? - sql

I am trying something like:
select name from myTable where id in (1056,1066,1069,1080,1404,1406,1407,3018)
But this is acting like OR condition and if I use AND between these values it does not give any result as it is trying to match in one cell.
Sample Data:
Name ID : abc 1 |abc 2| abc 3| def 2| fgh 3
My expected output is:
Name: abc
I want to find all the distinct names
having all corresponding ID's
Any pointer on this?

It seems you are confused on Logic, if you use AND then condition becomes false because there will not be any single row with ID having 1056 AND 1066.
for eg. suppose you have this table
ID name level
----------------
1056 abc bce
1066 bcd def
select name from myTable where id =1056 AND id=1066
now evaluate this with first row replacing id
1056 =1056 AND 1056=1066 (True AND False) is False
1066 =1056 AND 1066=1066 (False AND True) is False
So condition never becomes true so no rows are selected
Update
As per as your updated question, write like this
select distinct name from myTable where id in (1056,1066,1069,1080,1404,1406,1407,3018)

Ew. Multiple values in the same field?
select name from myTable
where id like '%1056%'
or id like '%1066%'
or id like '%1069%'
etc

Logically there is no output of your query, but if you want to use multiple ANDs once without writing writing AND multiple times, you can use Row Subqueries:
select name
from myTable
where (id,id,id,id,id,id,id,id)=(1056,1066,1069,1080,1404,1406,1407,3018)
is equal to:
select name
from myTable
where id =1056
AND id =1066
AND id =1069
AND id =1080
AND id =1404
AND id =1406
AND id =1407
AND id =3018

For the problem of this type, the best solution I could is use divide feature of Relational Algebra.
It will give the expected result.
Sample Example:-
http://coronet.iicm.tugraz.at/Dbase1/scripts/rdbh06.htm

Related

How to make a sql view where each row is the result of a query?

I am currently working on PostgreSQL version 14.
I got two tables, one is a list of emails, the other one describe if those emails are invalid or was marked as unsubscribe (black_list). I want to make the percentage of how many addresses are invalid and unsubscribed in two different rows in the same table using a view.
My email table
| email_id | email|
|:---- |:------:|
| 1| bob.smith#yahoo.com|
| 2| ronald.gregor#gmail.com|
| 3| jo123456#gmail.com|
My table black_list looks like that.
email_id
unsubscribe
invalid
1
True
False
3
False
True
The result I expect.
categories
value
unsubscribe
33
invalid
33
I tried to make a view with this query :
CREATE OR REPLACE VIEW percentage_unsubscribe (value) AS SELECT (SELECT COUNT(*)
FROM black_list WHERE unsubscribe = True)/(SELECT COUNT(*) FROM email_table
But i would like to know how to pass the categorical column and the second row.
Use union to generate two rows and the with statement to optimize the query a bit and make it more readable, e.g.:
create or replace view percentage_unsubscribe (category, value) as
with totals as (
select
count(*) filter (where unsubscribe) as unsubscribe,
count(*) filter (where invalid) as invalid,
(select count(*) from email_table) as total
from black_list
)
select 'unsubscribe', unsubscribe* 100/ total
from totals
union
select 'invalid', invalid* 100/ total
from totals;

Getting single record in Oracle/ Oracle APEX

I'm building a page in APEX. In that page I have 2 items, "text field with autocomplete" Both of them are getting the LOV from the same table but different column. text_field_1 getting the id_1; text_field_2 getting the id_2
So If I input/select a value from text_field_1 I can set a value automatically to text_field_2 or vice versa. I can do one is to one relationship, like if I enter "bca" in text_field_2, I can set the correct value for text_field_1 which is "2"
But I'm having a problem for the one is to many relationship. If I enter "1" in text_field_1, It will return 2 values which are "abc,cba" I'm trying to figure it out on how I list the abc and cba so that I can still choose what value I want from the two. Please someone help me with this?
This is my sample table
id_1
id_type_1
id_2
id_type_2
datetime
1
employee_id
abc
employee_code
01-01-1000 00:00:00
1
employee_id
cba
employee_code
02-01-1000 11:00:00
2
employee_id
bca
employee_code
01-01-1000 12:00:00
3
employee_id
acd
employee_code
01-02-1000 14:00:00
Thank you so much in advance. I really need this
If you use list of values, then that's exactly what its name says - a list of values. They are supposed to return more than a single row, that's perfectly normal and expected situation.
Therefore, your LOV1 (which is a "source" of e.g. P1_ITEM_1) should
select distinct id_1 as display_value,
id_1 as return_value
from your_table
while LOV2 would then have P1_ITEM_1 as a parent LOV item and
select id_2 as display_value,
id_2 as return_value
from your_table
where id_1 = :P1_ITEM_1
To answer what you asked:
if I select id_1 = 1 then I will get the 'abc' OR if I select the other id_1 = 1, I will get 'cba'
Can you do that? Sure; the question is which one of abc or cba you want. What we usually do is to select any of them using min or max aggregate function, e.g.
select max(id_2)
from your_table
where id_1 = :P1_ITEM_1
(you'd get cba as a result in this case).

Show values in another value in sql

I want show value 1 by 'this i number one' in result of query sql. I'm looking for a statement like ALIAS but using for values, not column.
Ex:
id|
0|
1|
1|
When excute query results sholud be:
id|
this is number zero|
this is number one|
this is number one|
Thanks!
Ex: i have table id that have 2 value 0,1. Can i using SELECT id FROM table WITH 0 AS zero AND 1 AS one;
I hope my result should be: id|zero|zero|one|...
If I correct understood, you need something like this:
with t(id) as (
select 0
union all
select 1
-- another values
)
select id as original_value,
CASE
WHEN id = 0 THEN 'zero'
WHEN id = 1 THEN 'one'
-- another values
END as changed_value
from t

Hive how is a group defined when calculating a functional group (Max, Min..) when scalar data is used in the same row?

In Hive a statement like this:
SELECT MIN('FOO') AS id,
MIN('Foo') as name;
will return a result set like this:
+------------+---------+
| id | name |
+------------+---------+
| Foo | Foo |
+------------+---------+
Even though I would expect :
FOO, Foo
(the Max('FOO') is the max value over a group of 1 and the Max('Foo') is the max value over another group of 1).
Using more than one function or appending a ' ' to one of the values produces the expected result.
SELECT MIN('FOO') AS id,
Max('Foo') as name;
or
SELECT MIN('FOO') AS id,
MIN(concat('Foo', '')) as name;
Is this a bug or does grouping in Hive work at a row level over all columns in the row with the same function case insensitively.
Try setting hive.cache.expr.evaluation=false
This might be related to this bug in Hive.

how to select one tuple in rows based on variable field value

I'm quite new into SQL and I'd like to make a SELECT statement to retrieve only the first row of a set base on a column value. I'll try to make it clearer with a table example.
Here is my table data :
chip_id | sample_id
-------------------
1 | 45
1 | 55
1 | 5986
2 | 453
2 | 12
3 | 4567
3 | 9
I'd like to have a SELECT statement that fetch the first line with chip_id=1,2,3
Like this :
chip_id | sample_id
-------------------
1 | 45 or 55 or whatever
2 | 12 or 453 ...
3 | 9 or ...
How can I do this?
Thanks
i'd probably:
set a variable =0
order your table by chip_id
read the table in row by row
if table[row]>variable, store the table[row] in a result array,increment variable
loop till done
return your result array
though depending on your DB,query and versions you'll probably get unpredictable/unreliable returns.
You can get one value using row_number():
select chip_id, sample_id
from (select chip_id, sample_id,
row_number() over (partition by chip_id order by rand()) as seqnum
) t
where seqnum = 1
This returns a random value. In SQL, tables are inherently unordered, so there is no concept of "first". You need an auto incrementing id or creation date or some way of defining "first" to get the "first".
If you have such a column, then replace rand() with the column.
Provided I understood your output, if you are using PostGreSQL 9, you can use this:
SELECT chip_id ,
string_agg(sample_id, ' or ')
FROM your_table
GROUP BY chip_id
You need to group your data with a GROUP BY query.
When you group, generally you want the max, the min, or some other values to represent your group. You can do sums, count, all kind of group operations.
For your example, you don't seem to want a specific group operation, so the query could be as simple as this one :
SELECT chip_id, MAX(sample_id)
FROM table
GROUP BY chip_id
This way you are retrieving the maximum sample_id for each of the chip_id.