This is my table1
ID || Basket || Balls
--------------------------
1 || Ram || 1
1 || Rom || 3
2 || Ram || 2
3 || Rom || 5
Query - Select all the IDs that have both at least 1 ball in both Ram and Rom.
----All the IDs that have at least 1 ball in Ram
SELECT distinct ID
INTO #RAM
FROM Table1
where balls > =1 and basket = 'Ram'
----All the IDs that have at least 1 ball in Rom
SELECT distinct ID
INTO #ROM
FROM Table1
where balls > =1 and basket = 'Rom'
---All the IDs that have both
Select distinct ID
INTO #FinalTable
from #RAM a join #ROM b on a.id = b.id
This is what I have written so far it works but I feel there is definitely a more efficient way to do this.
Please let me know. Thank you.
I would use a single aggregation:
select id
from table1 t1
group by id
having sum(case when basket = 'Ram' then balls end) > 0 and
sum(case when basket = 'Rom' then balls end) > 0;
Assuming the value of balls is never negative or zero, then you only need to check that that the rows exist. That is a little simpler in MySQL:
select id
from table1 t1
group by id
having sum(basket = 'Ram') > 0 and
sum(basket = 'Rom') > 0;
You can use subqueries to achieve this.
join RAM
join ROM
select count() >= 1
select t1.ID
from Table1 t1
join
(select ID, count(1) ct from Table1 where Basket = 'Ram'
group by ID) as ram on ram.ID = t1.ID
join
(select ID, count(1) ct from Table1 where Basket = 'Rom'
group by ID) as rom as rom.ID = t1.ID
where ram.ct >= 1 and rom.ct >= 1
You need Only t use this query and combine your Queries
SELECT
a.ID
FROM (SELECT ID FROM Table1 Where Balls >= 1 And Basket = 'RAM') a
INNER JOIN (SELECT ID FROM Table1 Where Balls >= 1 And Basket = 'ROM') b
ON a.ID = b.ID
It only return the OD that are have nmore than 1 ball and are in RoM and RAM
We can group by based on ID,Basket and select records having count greater than 1
select distinct a.id from
(
select id,basket,count(balls) as cn
from table1
group by id,basket
having cn>1
) a ;
Related
Considering here is my table query:
id name number Code
1 red 1 A
2 red 3 B
3 blue 3 C
4 blue 5 A
5 purple 2 D
6 yellow 3 D
7 yellow 4 C
Now I need to query to get 2 random row such that there is 1 name is red and 1 number is 3, kinda like this:
SELECT * FROM table WHERE name = "red" LIMIT 1 and number = 3 LIMIT 1
So like row 1+3,1+6 or 2 + any other row.
Here is my query:
SELECT * FROM table
group by name,number
having count(name="red") = 1
and count(number=3) = 1
ORDER BY RAND()
LIMIT 2;
However, it seems like it just query the row randomly and not satisfying my requirement. Can anyone show me what is wrong ?
Thank you.
I think that this will do what you want:
select t1.*
from tablename t1
inner join (
select t1.id id1, t2.id id2
from tablename t1 inner join tablename t2
on t2.id > t1.id
and ('red' in (t1.name, t2.name)) + ('3' in (t1.number, t2.number)) = 2
order by rand() limit 1
) t2 on t1.id in (t2.id1, t2.id2)
Note that the row with the highest probability to be returned is id = 2, because it can be combined with any other row of the table.
See the demo.
If you can live with odd formatting...
select x.id x_id
, x.name x_name
, x.number x_number
, x.code x_code
, y.id y_id
, y.name y_name
, y.number y_number
, y.code y_code
from my_table x
join my_table y
on y.id <> x.id
where x.name = 'red'
and y.number = 3
order by rand()
limit 1;
https://www.db-fiddle.com/f/6JmLKq1RwaPrSwS3zx4Qmt/0
Previously, I posted this solution, but it too has some flaws, I think. But TB liked it, so I'll keep it here...
select *
from my_table where name = 'red'
union distinct
select *
from my_table where number = 3
order by rand()
limit 2
How would I return the ProductNumbers where the Number is duplicated when it has the same year ?
This is all within the same table.
in this example below, I would expect ProductNumber 123 and 456 to be returned.
Explain reasoning if possible, thank you!
ProductNumber Numb Year
123 45 1
456 45 1
789 45 2
109 54 2
Here's one option using exists:
select *
from yourtable t
where exists (
select 1
from yourtable t2
where t.productnumber != t2.productnumber
and t.numb = t2.numb
and t.year = t2.year
)
Using exists, we check to see if there are other records in the same table whose productnumber is different, but have the same numb and year values.
You can use EXISTS() :
SELECT *
FROM Table T1
WHERE EXISTS
(
SELECT 1
FROM
(SELECT Numb ,Year
FROM Table
GROUP BY Numb
,Year
HAVING COUNT(1)>1
) T2
WHERE T1.Numb = T2.Tumb
AND T1.Year = T2.Year
)
You can also use INNER JOIN
SELECT t1.ProductNumber
FROM Products t1
INNER JOIN Products as t2
ON t1.ProductNumber != t2.ProductNumber
AND t1.Numb = t2.Numb
AND t1.Year = t2.Year
please advice how to make SQL query in order to get from this table
ID|Number|Type|
----------------
1 |AA1 |IN |
2 |AA2 |OUT |
3 |AA3 |IN |
4 |AA4 |OUT |
into this result
ID| IN | OUT |
-------------------
1 | AA1 | AA2 |
2 | AA3 | AA4 |
Thanks
This Will work using Implicit join.
It will use mysql session variables. for reference, you can read http://www.mysqltutorial.org/mysql-variables/ for session variables.
SET #row_number = 0;
SET #row_number2 = 0;
SELECT
out_table.OUTs AS outs, in_table.Ins as INs FROM
(SELECT
(#row_number2:=#row_number2 + 1) AS num2, Number as OUTs FROM your_table WHERE your_table.Type = 'OUT') as out_table ,
(SELECT
(#row_number:=#row_number + 1) AS num1, Number as Ins FROM your_table WHERE your_table.Type = 'IN') as in_table
WHERE num2 = num1
You can emulate row_number like functionality, using session variables. We get all INs and OUTs separately in two derived tables and do a LEFT JOIN on them, to get the desired output.
This will work even for the cases where IN and OUT are not consecutive. It will also handle the cases where there is an IN without OUT.
It would not work for the case when there is an OUT without IN.
Try the following query:
SET #row_no_1 = 0;
SET #row_no_2 = 0;
SELECT
t1.row_no AS ID, t1.Number AS `IN`, t2.Number AS `OUT`
FROM
(SELECT
#row_no_1:=#row_no_1 + 1 AS row_no, Number
FROM
`your_table`
WHERE
Type = 'IN'
ORDER BY id ASC) AS t1
LEFT JOIN
(SELECT
#row_no_2:=#row_no_2 + 1 AS row_no, Number
FROM
`your_table`
WHERE
Type = 'OUT'
ORDER BY id ASC) AS t2 ON t2.row_no = t1.row_no
answering myself...
SELECT a.ID
MAX(CASE WHEN a.type = "IN" THEN a.Number ELSE "" END) AS IN_Type,
MAX(CASE WHEN b.type = "IN" THEN b.Number ELSE "" END) AS Out_Type
FROM table1 a Left join table1 b on a.ID = b.ID
Group by a.ID
I have 2 tables in Mysql which looks as follows
Table 1
ID YEARMONTH
------------------
1 201210
2 201211
3 201212
Table2
ID YEARMONTH GRADE DESIG
--------------------------------
1 201210 G1 NULL
2 201210 G1 D2
3 201212 G1 D1
I am trying to set a new field (named FLAG) in table1 which will be Y if rows exist for t1.YEARMONTH in T2 else N
I want the following Result in T1
ID YEARMONTH FLAG
---------------------
1 201210 Y
2 201211 N
3 201212 Y
I have tried the following Query
SELECT
T1.ID,
T1.YEARMONTH,
CASE COUNT(T2.ID)
WHEN (SELECT
COUNT(T2.ID)
FROM TABLE2 T2)
> 0 THEN 'Y'
ELSE 'N'
END AS flag
FROM TABLE1 T1,
table2 T2;
But it produces the following output
ID YEARMONTH FLAG
---------------------------
1 201210 N
I don't know where my mistake lies. Any help would be appreciated.
Try using the below query:
SELECT
T1.ID, T1.YEARMONTH,
(CASE
WHEN COUNT(T2.ID) > 0 THEN 'Y'
ELSE 'N'
END) AS FLAG
FROM TABLE1 T1
LEFT JOIN TABLE2 T2
ON T1.YEARMONTH = T2.YEARMONTH
GROUP BY T1.ID, T1.YEARMONTH
You can see the required output here http://sqlfiddle.com/#!9/162855/12
TRY THIS: Using CASE with LEFT JOIN you can check the existence of t1.yearmonth in t2.yearmonth and generate the flag column accordingly
SELECT DISTINCT t1.id,
t1.yearmonth,
(CASE WHEN t2.yearmonth IS NOT NULL THEN 'y' ELSE 'n' END) flag
FROM table1 t1
LEFT JOIN table2 t2 ON t1.yearmonth = t2.yearmonth
i've got a DB like this
id name group
with data like this
1 john A
2 john B
3 charles B
4 peter B
5 rose B
6 charles A
7 justin C
As you can see, the posibilities are that one ID it's associated with one group, or more than one group
i need a query for filtering
a) are in group A and B
b) are in group A but not B
c) are only in group A
a. select distinct name from tablename where group = 'A' or group = 'B';
b. select distinct name from tablename where group = 'A' and group <> 'B';
c. select distinct name from tablename where group = 'A' and
group not in (select distinct(t1.group) from tablename t1
where t1.group <> 'A');
I like approaching these problems using group by and the having clause. For your first question:
select name
from table
group by name
having sum(group = 'A') > 1 and sum(group = 'B') > 0;
The other two are:
having sum(group = 'A') > 1 and sum(group = 'B') = 0;
having sum(group = 'A') > 1 and sum(group <> 'A') = 0;