Using join in place of this two seperate queries - mysql

I have a table by the following structure and records, All i want to do is to just extract list_name of those records whose uid is either 0 or 2 , but i also want to check if a record is available for uid 0 and 2 , then only it should show only record with uid 2... I have managed to do this with two queries... Can i write a single query for this...
**id** **uid** **list_name**
1 2 favourite list
2 0 Things i love
3 0 my list
4 2 my lists
5 3 test334
6 2 Things i love
Any help or suggestion will be highly appreciated ..Thanks in advance..

Another guess:
SELECT
uid, list_name
FROM
myTable T1
WHERE
uid = 2
OR
( uid = 0
AND NOT EXISTS
( SELECT *
FROM myTable T2
WHERE T2.uid = 2
AND T2.list_name = T1.list_name
)
)

A guess...
SELECT
list_name
FROM
myTable T1
WHERE
uid IN (0, 2)
AND
NOT EXISTS (SELECT * FROM myTable T2 WHERE T2.uid = 0)
UNION ALL
SELECT
list_name
FROM
myTable T1
WHERE
uid = 2
AND
EXISTS (SELECT * FROM myTable T2 WHERE T2.uid = 0)

Related

Mysql query, eliminate name having assets less than 10, but still show all the data

This is my data that I have, I want to show all names that contain assets > 10, but still showing all assets that < 10.
id name assets
1 'Mira' 10
2 'Mira' 9
3 'Maulana' 10
4 'Maulana' 5
5 'Fifi' 4
6 'Fifi' 6
Goals
id name assets
1 'Mira' 10
2 'Mira' 9
3 'Maulana' 10
4 'Maulana' 5
use exists
select t1.* from table t1
where exists ( select 1 from table t2 where t1.name=t2.name and t2.assets>10)
note: it seems to me you need >=10 but your description no like that so i have used >10
One approach uses an EXISTS clause to check each name for the presence of a record having assets > 10:
SELECT id, name, assets
FROM yourTable t1
WHERE EXISTS (SELECT 1 FROM yourTable t2 WHERE t2.name = t1.name AND t2.assets > 10);
Another option would be to use aggregation:
SELECT t1.id, t1.name, t1.assets
FROM yourTable t1
INNER JOIN
(
SELECT name
FROM yourTable
GROUP BY name
HAVING SUM(assets > 10) > 0
) t2
ON t1.name = t2.name;

how to exclude first and last row if group it on particular id

I have sample table with data like this
id uniqueid values
1 6 0
2 6 1
3 6 2
4 6 0
5 6 1
I want result like this
id uniqueid values
2 6 1
3 6 2
4 6 0
I tried like this
select id,uniqueid,values
FROM t1
WHERE
id not in(SELECT concat(MAX(message_id_pk),',',min(message_id_pk)) FROM t1
where uniqueid=6)
and `uniqueid`=6
GROUP BY uniqueid
but its not working
You can achieve the desired results by doing self join, Inner query will get the the max and min ids for per group and outer query will filter out the results by using minid and maxid
select a.*
from demo a
join (
select `uniqueid`,min(id) minid, max(id) maxid
from demo
where uniqueid=6
group by `uniqueid`
) b using(`uniqueid`)
where a.id > b.minid and a.id < b.maxid /* a.id <> b.minid and a.id <> b.maxid */
Demo
Also you can do it by using 2 sub-queries with EXISTS to exclude the min and max id of each uniqueid.
Query
select `id`, `uniqueid`, `values`
from `your_table_name` t1
where exists (
select 1 from `your_table_name` t2
where t2.`uniqueid` = t1.`uniqueid`
and t2.`id` > t1.`id`
)
and exists(
select 1 from `your_table_name` t2
where t2.`uniqueid` = t1.`uniqueid`
and t2.`id` < t1.`id`
);
Here is a sql fiddle demo
Try this -
SELECT id, uniqueid, values
FROM YOUR_TABLE
WHERE id NOT IN (MIN(id), MAX(id));

Using a nested query to get details of two tables

TABLE 1 TABLE 2
id name mob id course mark
1 joe 0000 1 English 77
2 john 0000 2 maths 89
I need to show the name of the person from table 1 who has the MAX(grade) in table 2 using a nested query.
SELECT t1.name
FROM t1
WHERE t1.id = t2.id = (
SELECT id
FROM t2
WHERE mark =
(
SELECT MAX(mark)
FROM t2
)
);
Well, this satisfies the brief ;-):
SELECT a.*
FROM table_a a
JOIN (SELECT * FROM table_b) b
ON b.id = a.id
ORDER
BY mark DESC
LIMIT 1;

Fetch duplicate rows with SQL

I am trying to develope a query to fetch the rows having duplicate values, i need to fetch both records i.e duplicating record and the real one, for example
table
id keyword
-------------------
1 Apple
2 Orange
3 Apple
4 Grape
5 Banana
6 Grape
The query result should be:
id keyword
-------------------
1 Apple
3 Apple
4 Grape
6 Grape
Please anyone help me!
Query:
select * from
table where keyword in
(select keyword
from table
group by keyword
having count(keyword)>1)
One way to do it:
SELECT *
FROM `table` t1
WHERE
(SELECT COUNT(*) FROM `table` t2 WHERE t2.keyword = t1.keyword) > 1
And another way:
SELECT t1.*
FROM `table` t1
JOIN `table` t2 ON t1.keyword = t2.keyword
WHERE t1.id != t2.id
This might help:
SELECT t1.id, t1.keyword
FROM table t1
INNER JOIN table t2
ON t1.id != t2.id
AND t1.keyword=t2.keyword
Tested on SQL Fiddle
http://sqlfiddle.com/#!2/44dbb/1/0

Group dates based on variable periods

i have two tables as follows------
table-1
CalenderType periodNumber periodstartdate
1 1 01-01-2013
1 2 11-01-2013
1 3 15-01-2013
1 4 25-01-2013
2 1 01-01-2013
2 2 15-01-2013
2 3 20-01-2013
2 4 25-01-2013
table2
Incidents Date
xyz 02-01-2013
xxyyzz 03-01-2013
ccvvb 12-01-2013
vvfg 16-01-2013
x3 17-01-2013
x5 24-01-2013
Now i want to find out the number of incidents took place in a given period(the Calendar type may change on runtime like)
the query should look something like this
select .......
from ......
where CalendarType=1
which should return
CalendarType PeriodNumber Incidents
1 1 2
1 2 1
1 3 3
1 4 0
can someone suggest me an approach or any method how this can be achieved.
Note:each period is variable in size.peroid1 may have 10 days period2 may have 5 days etc.
I think this does what you want, although I don't understand how you arrived at your sample output:
select t.CalenderType, t.periodNumber, count(*) as Incidents
from Table1 t
inner join (
select t2.Date, t2.Incidents, max(t1.periodstartdate) as PeriodStartDate
from Table2 t2
inner join Table1 t1 on t2.Date >= t1.periodstartdate
where CalenderType = 1
group by t2.Date, t2.Incidents
) a on t.periodstartdate = a.PeriodStartDate
where CalenderType=1
group by t.CalenderType, t.periodNumber
SQL Fiddle Example
Try this, a bit more general solution,SQLFiddle (Thanks RedFilter for schema):
SELECT t1.CalenderType, t1.periodNumber, count(Incidents)
FROM Table1 t1, Table1 t11, Table2
WHERE
(
(
t1.CalenderType = t11.CalenderType
AND t1.periodNumber = t11.periodNumber - 1
AND Date BETWEEN t1.periodstartdate AND t11.periodstartdate
)
OR
(
t1.periodNumber = (SELECT MAX(periodNumber) FROM Table1 WHERE t1.CalenderType = CalenderType)
AND Date > t1.periodstartdate
)
)
GROUP BY t1.CalenderType, t1.periodNumber
ORDER BY t1.CalenderType, t1.periodNumber