Let's have a table named employers with columns:
id
cash
and I need to select id and cash for employers that have minimal cash lower than minimal cash in rows with id = 2.
An example of the table:
----------
id cash
----------
1 100
2 200
2 150
2 125
3 320
4 400
It should select only the first row, because minimal cash in rows with id 2 is 125 and only this row has lower cash.
I tried something like this but it didn't work:
SELECT id, MIN(cash)
FROM employers
WHERE cash < (MIN(cash)
WHERE id = 2;
Try the following query
SELECT id, cash
FROM employers
WHERE cash < (SELECT MIN(cash)
FROM employers
WHERE id = 2
GROUP BY id);
EDIT: Removed the MIN from the query, this should work with your data sample.
Also I suggest that you modify the query based on your requirements.
In case you need only the least cash available at every employer, who has less cash than the min cash, then use a GROUP BY id and select MIN(cash).
SELECT T1.ID, min(T1.cash), T2.Id, min(T2.Cash)
FROM Table T1
CROSS JOIN table T2
WHERE T1.CASH < T2.CASH
and T2.ID = 2
and T1.ID <> 2
GROUP BY T1.ID, T2.ID
Related
I have two tables, one holds some categories and the other holds players' records like so:
Categories Times
id Name id UserId MapId CategoryId Time
1 cat1 1 1 1 1 1500
2 cat2 2 3 1 2 3000
3 cat3 3 13 1 3 2500
4 cat4 4 12 1 4 1500
5 cat5 5 11 1 4 1000
I want to select all the categories (id, name) and the lowest time on each category.
If there's no record on that category it should show NULL or 0.
This would be the expected result:
Result
id Name Time
1 cat1 1500
2 cat2 3000
3 cat3 2500
4 cat4 1000
5 cat5 0
I'm using the following query, but it only selects the categories that already have a record in Times.
For example, if I use the following query it'll not select 'cat5' because it doesn't have any record in table Times.
select t2.id, t2.Name, min(t1.Time) as Time
from Times t1
join Categories t2 on t2.id = t1.CategoryId
where t1.MapId = %MAPID%
group by t2.id
I recommend to begin your query with the table "categories" in this case since your focus is on the data from this table. So you could write a left join. Furthermore, I think it's a good idea to replace null values by zero, thus your query would as example find negative times as the lowest times and return 0 if the lowest time is a null value.
Overall, this could be your goal:
SELECT c.id, c.name, MIN(COALESCE(t.time,0)) AS time
FROM categories c LEFT JOIN times t ON c.id = t.categoryid
GROUP BY c.id, c.name;
Here is a working example according to your sample data: db<>fiddle
There are likely also other options to achieve your goal, you can just try out.
I think you might just need to do a right join (because you want all rows from the 2nd table listed -- Categories). See if you get the desired results by changing line 3 to be:
right join Categories t2 on t2.id = t1.CategoryId
I have a table T1 as below
product_id val
123,567 5
999 4
999 3
and another table T2,
t_product_id // this maps to product_id in above table
123
999
In the final output, for t_product_id in table T2 I have to get value for it from T1. For duplicate product_ids (999) I want to get the min value, and for 123 I want to get 5
This is how output should look like
product_id value
123 5
999 3
My query ->
select t1.product_id, min(t1.value)
from T1 t1
group by t1.product_id
I am not sure what needs to be done next. How to separate comma separated values and check if 123 from T2 exists in T1 and get the value for it
it's not possible to keep only one product_id per row in table T1?
I think this would simplify matters for you. T1 would be:
123 | 5
567 | 5
999 | 4
999 | 3
Use join to only select the ids that exist in T2
select t1.product_id, min(t1.value)
from T1 t1 join T2 on (t1.product_id = t2.t_product_id)
group by t1.product_id
I have a dataset that I want to sum the values for by category (item), however before I sum them together I need to convert the currency of some values dependent on the currency in another column.
Sample dataset:
Item Currency Value
1 USD 10
1 PHP 100
2 USD 50
2 PHP 1000
3 PHP 500
select ITEM,
(case when CURRENCY='usd' then sum(VALUE*2) else sum(VALUE) end ) VALUE
from TABLE1
inner join TABLE2 on TABLE1.ID=TABLE2.ID
inner join TABLE3 on TABLE3.X=TABLE1.X
inner join TABLE4 on TABLE1.Y=TABLE4.Y
where A=1 and B=2 and C=5
group by ITEM, CURRENCY
ORDER BY ITEM asc
Desired outcome (using x2 as a factor to go from USD to PHP):
Item Value
1 120
2 1100
3 500
However, I am getting the following, which has correctly converted the currency, but is not grouping by item (ie. i'm getting duplicated rows for item rather than 1 row with the summed value):
Item Value
1 20
1 100
2 100
2 1000
3 500
The case should be the argument to the SUM():
select ITEM,
sum(case when CURRENCY='usd' then VALUE*2 else VALUE
end ) as VALUE
from TABLE1 join
TABLE2
on TABLE1.ID = TABLE2.ID join
TABLE3
on TABLE3.X = TABLE1.X join
TABLE4
on TABLE1.Y = TABLE4.Y
where A = 1 and B = 2 and C = 5
group by ITEM
ORDER BY ITEM asc;
Note: The GROUP BY is only by ITEM, because that defines the rows you want in the result set.
I tried below query to bring all rows after last Action="UNLOCKED", but ORDER BY is not allowed in subquery it seems.
SELECT *
FROM TABLE
WHERE id >= (SELECT MAX(id)
FROM TABLE
WHERE ACTION='UNLOCKED' AND action_id=123
ORDER BY CREATE_DATE DESC);
Sample data
Id action_id Action ... CREATE_DATE
1 123 ADD 03/18/2018
2 123 Unlocked 03/19/2018
3 123 Updated1 03/19/2018
4 123 Updated2 03/19/2018
5 123 Unlocked 03/20/2018
6 123 Updated3 03/20/2018
7 123 Updated4 03/20/2018
Output should be rows with id 5,6,7. What should i use to get this output
you could use an inner join on subselect for max create_date
select * from TABLE
INNER JOIN (
select max(CREATE_DATE) max_date
from TABLE
where Action = 'Unlocked' ) T on t.max_date = TABLE.CREATE_DATE
You need not order the inner query because it will return only one value. You can do it as follows
SELECT * FROM TABLE WHERE id >= (select max(id) from TABLE where ACTION='UNLOCKED' and action_id=123);
Suppose I have table with following values
A B C
------------------------
5 ABC $20
3 BCD $40
5 BCD $40
2 ABC $20
5 ABC $30
How to write query which would return count of maximum, suppose for column A
it should return value 3 that is count for max which is 5.
You can use sub-query like this one:
SELECT COUNT(*) AS COUNTS FROM Table1
WHERE A = (SELECT MAX(A) AS AD FROM Table1)
See this SQLFiddle
One way (not sure it's the fastest):
SELECT A, count(*) FROM my_table GROUP BY 1 ORDER BY 2 LIMIT 1;
Although not as typical this works as well
(Self anti-join on an inequality)
SELECT
COUNT(t1.a) AS COUNTS
FROM Table1 t1
LEFT JOIN Table1 t2
ON t1.A < t2.A
WHERE
t2.a is null
Demo