I need to create a query look like this
select *
from users
where name = 'A'
if and only if no result THEN
name = 'B';
I don't want to get the two rows where first row name = A and second row name = B
I need just one of them
is there any way to do that in sql ?
I tried to achive that with not exists or case but couldn't make it work
Thank you
Since 'A' is before 'B' alphabetically then, from Oracle 12, you can use:
SELECT *
FROM users
WHERE name IN ('A', 'B')
ORDER BY name
FETCH FIRST ROW WITH TIES;
If you do not want to rely on alphabetic ordering then:
SELECT *
FROM users
WHERE name IN ('A', 'B')
ORDER BY CASE name WHEN 'A' THEN 1 ELSE 2 END
FETCH FIRST ROW WITH TIES;
If you want to apply a different ORDER BY clause then use a sub-query:
SELECT *
FROM (
SELECT *
FROM users
WHERE name IN ('A', 'B')
ORDER BY CASE name WHEN 'A' THEN 1 ELSE 2 END
FETCH FIRST ROW WITH TIES
)
ORDER BY col1, col2;
In earlier versions, you can use the RANK analytic function (or DENSE_RANK):
SELECT *
FROM (
SELECT u.*,
RANK() OVER (ORDER BY CASE name WHEN 'A' THEN 1 ELSE 2 END) AS rnk
FROM users u
WHERE name IN ('A', 'B')
)
WHERE rnk = 1
db<>fiddle here
Related
Column 1 "Letter": A, B, C
Column 2 "Name": Apple, Boat, Cat
I need a query to get the name value if the letter value equal to A. In case that no A, so return the name for B. So, I need to get one record at the end.
Please help
Order by letter and, from Oracle 12, FETCH FIRST ROW ONLY:
SELECT name
FROM table_name
ORDER BY letter
FETCH FIRST ROW ONLY
or, in earlier versions, order and then filter by the ROWNUM pseudo-column:
SELECT *
FROM (
SELECT name
FROM table_name
ORDER BY letter
)
WHERE ROWNUM = 1
If you only want A or B values then add a WHERE filter:
SELECT name
FROM table_name
WHERE letter IN ('A', 'B')
ORDER BY letter
FETCH FIRST ROW ONLY
or:
SELECT *
FROM (
SELECT name
FROM table_name
WHERE letter IN ('A', 'B')
ORDER BY letter
)
WHERE ROWNUM = 1
Which, for your sample data, output:
NAME
Apple
fiddle
I'm working with a dataset - structured like this
I want to exclude all records with ReviewRound being "a" if they have gone through review round "b" - If a set of unique ID's has an associated round "b" review, the round "a" review should not be included.
Some records have not gone to round "b". The issues I'm running into are as a result of there being multiple records for each unique ID.
Ideally this could be done in GoogleBigQuery, if not, filtering through GoogleScripts may also be an option!
Any suggestions would be appreciated!
If a set of unique ID's has an associated round "b" review, the round "a" review should not be included.
If I followed you correctly, you could express this as a not condition with a correlated subquery that ensures that, if the current record has ReviewRound = 'a', there is no other record that has the same id and ReviewRound = 'b'.
select t.*
from mytable t
where not (
t.ReviewRound = 'a'
and exists (
select 1
from mytable t1
and t1.id = t.id and t1.ReviewRound = 'b'
)
)
You can do this with window functions as well:
select t.* except (num_bs)
from (select t.*,
countif(reviewround = 'b') over (partition by id) as num_bs
from t
) t
where num_bs = 0 or reviewround = 'b';
By using window functions, you can solve it with this query
SELECT ID, Score
FROM (
SELECT *,
MAX(CASE WHEN ReviewRound = 'b' THEN 1 ELSE 0 END) OVER (partition by ID) as has_b
FROM mytable
) t
WHERE has_b = 0
Re-conceptualizing as keeping only the latest review round, I would try:
select * from mytable join
(select ID, max(ReviewRound) as ReviewRound from mytable group by ID)
on (ID, ReviewRound)
I have muliple products tagged to same ID , I want to show the ID once with the products in the single column separated by '/'.
eg. If 123 has A and B in separate rows then output should be 1 A/B in different columns.
select
d.*,
case when d.col = 'A' AND d.loan_class = 'B'
then 'A/B'
else 'NA'
end name
From tab D
where id = '1'
Group By ....;
Isn't that LISTAGG?
select id,
listagg(product, '/') within group (order by null) list_of_products
from your_table
group by id
How to find all column values are same in Group by of rows in table
CREATE TABLE #Temp (ID int,Value char(1))
insert into #Temp (ID ,Value ) ( Select 1 ,'A' union all Select 1 ,'W' union all Select 1 ,'I' union all Select 2 ,'I' union all Select 2 ,'I' union all Select 3 ,'A' union all Select 3 ,'B' union all Select 3 ,'1' )
select * from #Temp
Sample Table:
How to find all column value of 'Value' column are same or not if group by 'ID' Column.
Ex: select ID from #Temp group by ID
For ID 1 - Value column records are A, W, I - Not Same
For ID 2 - Value column records are I, I - Same
For ID 3 - Value column records are A, B, 1 - Not Same
I want the query to get a result like below
When all items in the group are the same, COUNT(DISTINCT Value) would be 1:
SELECT Id
, CASE WHEN COUNT(DISTINCT Value)=1 THEN 'Same' ELSE 'Not Same' END AS Result
FROM MyTable
GROUP BY Id
If you're using T-SQL, perhaps this will work for you:
SELECT t.ID,
CASE WHEN MAX(t.RN) > 1 THEN 'Same' ELSE 'Not Same' END AS GroupResults
FROM(
SELECT *, ROW_NUMBER() OVER(PARTITION BY ID, VALUE ORDER BY ID) RN
FROM #Temp
) t
GROUP BY t.ID
Usally that's rather easy: Aggregate per ID and count distinct values or compare minimum and maximum value.
However, neither COUNT(DISTINCT value) nor MIN(value) nor MAX(value) take nulls into consideration. So for an ID having value 'A' and null, these would detect uniqueness. Maybe this is what you want or nulls don't even occur in your data.
But if you want nulls to count as a value, then select distinct values first (where null gets a row too) and count then:
select id, case when count(*) = 1 then 'same' else 'not same' end as result
from (select distinct id, value from #temp) dist
group by id
order by id;
Rextester demo: http://rextester.com/KCZD88697
Assume i have a table:
I want that row with UserId ='ee' always display at row number one every time i select this table in SQLQuery.
Is it possible?
select *
from your_table
order by UserId <> 'ee' -- "<>", because false < true
or (arguably clearer):
select *
from your_table
order by case when UserId = 'ee' then 0 else 1 end
Use a view:
CREATE VIEW myView AS
SELECT * FROM myTable ORDER BY (case when UserId = 'ee' then 0 else 1 end) ASC
You can use the CASE Clause or IF Clause to change to order.
Example:
SELECT * FROM
Table
ORDER BY (CASE WHEN UserID = 'ee' THEN 1 ELSE 2 END) ASC, UserID ASC
Or
SELECT * FROM
Table
ORDER BY IIF(UserID = 'ee', 1, 2) ASC, UserID ASC
This way you give te ee value number 1 and all the others number 2 and order by those numbers. When those are ordered you order the duplicated 2's by the UserID itself.