Run SQL statement based on sql count - mysql

I want to run one SQL query based on first COUNT sql query:
SET #result = "SELECT count(*) FROM ip_addresses WHERE id > (SELECT id FROM ip_addresses WHERE in_use=1) ORDER BY id LIMIT 1"
CASE WHEN (#result > 0)
THEN SELECT * FROM ip_addresses WHERE id > (SELECT id FROM ip_addresses WHERE in_use=1) ORDER BY id LIMIT 1
ELSE SELECT * FROM ip_addresses WHERE in_use!=1 ORDER BY id LIMIT 1
END
Basically what I'm trying to do is, I want to get the next record in_use=0 of WHERE in_use=1. And if the in_use=1 record is last record of the table it should get the first record of table with in_use=0.
More explaination:
if ip_addresses table have following data
id| ip |in_use
1 | 192.168.1.5|1
2 | 89.58.1.2 |0
3 | 58.98.58.6 |0
Now it should return second record.
And if ip_addresses table have following data
id| ip |in_use
1 | 192.168.1.5|0
2 | 89.58.1.2 |0
3 | 58.98.58.6 |1
Now it should return first record.

You have several issues. The most important is that control flow logic is only allowed in programming blocks.
However, you can accomplish what you want with a single query. For instance:
(SELECT ia.*, 1 as priority
FROM ip_addresses ia
WHERE id > (SELECT id FROM ip_addresses WHERE in_use = 1)
ORDER BY id
LIMIT 1
)
UNION ALL
(SELECT ia.*, 2 as priority
FROM ip_addresses ia
WHERE in_use <> 1
ORDER BY id
LIMIT 1
)
ORDER BY priority
LIMIT 1

Building on xQbert's answer:
select IP
from ( select case when id >
( select min( ID )
from IP_ADDRESES
where in_use = 1 )
then ID - ( select max( ID ) from IP_ADDRESES )
else id
end case
from IP_ADDRESES as deflated_id,
ip )
order by deflated_id asc
top 1

SELECT A.IP
FROM IP_Addresses A,
( SELECT min(ID) mid
FROM IP_ADDRESES
WHERE in_use= 0
) B
WHERE A.id = B.mid;

Related

get the total count but exclude certain condition

Hello I had this table:
id | user_id | status
1 | 34 | x
2 | 35 | x
3 | 42 | x
4 | 42 | y
My goal is to count the data with X status except if the user has a another data with Y status, it will exclude in the count. So instead of 3, it will only count 2 since the 3rd row has another data which is the 4th row with y status.
SELECT * FROM logs
AND user_id NOT IN (SELECT user_id FROM logs WHERE status = 'y')
GROUP BY user_id;
We can try the following aggregation approach:
SELECT COUNT(*) AS cnt
FROM
(
SELECT user_id
FROM logs
GROUP BY user_id
HAVING MIN(status) = MAX(status) AND
MIN(status) = 'x'
) t;
The above logic only counts a user having one or more records only having x status.
You can do it this way, I only modify a bit on your sql
SELECT COUNT(*) FROM (
SELECT u_id FROM tbl WHERE u_id NOT IN
(SELECT u_id FROM tbl WHERE status = 'y')
GROUP BY u_id
) as t
You can use inner join:
SELECT
count(t1.id) AS `cnt`
FROM
`test` AS t1,
`test` AS t2
WHERE
t2.`status`='y'
&& t1.`user_id` != t2.`user_id`;

How can I select adjacent row in sql when ordered by a different field?

I've got a table of data with the following structure:
id | likes
1 | 2
2 | 5
3 | 2
4 | 6
5 | 2
If want to find the row next to #3 I can use :
SELECT * FROM table WHERE id >= 3 ORDER BY id
However what I want to do is order by table by likes. When the data is ordered by likes it looks like this
id | likes
1 | 2
3 | 2
5 | 2
2 | 5
4 | 6
How can I select the rows before or after a certain id when ordered by likes?
e.g. for id 5, my result would be row id 3 before and row id 2 after.
If likes are unique numbers, following should work.
previous:
SELECT * FROM table WHERE likes < (SELECT likes FROM table WHERE id = ID) ORDER BY likes DESC LIMIT 1
next:
SELECT * FROM table WHERE likes > (SELECT likes FROM table WHERE id = ID) ORDER BY likes ASC LIMIT 1
You may change 1 of them to <= or >= and add WHERE id != ID
Your second table shows wrong ids for the first two rows, by the way.
It should be:
id likes
1 2
3 2
This works in MySQL for me:
Select id, likes from (SELECT id, #rownum:=#rownum+1 AS rownum, likes
FROM table u, (SELECT #rownum:=0) r ORDER BY likes) as derived where
rownum >= 2 and rownum <= 4;
(SELECT id, #rownum:=#rownum+1 AS rownum, likes FROM table u, (SELECT
#rownum:=0) r ORDER BY likes);
The last part tries to simulate the row number, which is missing in MySQL, but available in MSSQL, Oracle and others.

Select Query to get last 3 calls and mails

I have 2 tables. One of tables has all mails from users and other table has all calls from users.
Table 1
call_id, | call_date | user_id
1 | 10/01/12| 3
2 | 9/01/12 | 3
Table 2
mail_id, | mail_date | user_id
1 | 8/01/12 | 3
2 7/01/12 | 3
I need to get last last 3 calls and mails :
10/01/12 - call
9/01/12 - call
8/01/12 - mail
Assuming MySQL, and for just one User_ID...
SELECT
*
FROM
(
SELECT 'call' AS type, id, call_date AS event_date, user_id FROM table_1
UNION ALL
SELECT 'mail' AS type, id, mail_date AS event_date, user_id FROM table_2
)
data
WHERE
user_id = 3
ORDER BY
event_date DESC
LIMIT
3
EDIT: Ooops, forgot to specify DESC in the ORDER BY, sorry.
Declare #userID int;
SET #userID=3;
select call_id FROM table_1
where user_id=#userID
order by call_date desc limit 2
UNION ALL
select mail_id FROM table_2
where user_id=#userID
order by mail_date desc limit 1

SQL get all rows sorted without duplicates

I have a table that looks something like this:
________________________
|id|value|date|approved|
-----------------------
What I need to be able to do is get each row where approved = 1. That part is obvious. For each occurrence of value, I only want the most recent row (sorted by date).
Meaning that with a table like this:
________________________
|id|value|date|approved|
-----------------------
|1 |Foo | 5 | 1 |
|2 |Bar | 6 | 1 |
|3 |Foo | 8 | 1 |
-----------------------
I only want the rows with id 2 and 3.
I assume I need to use DISTINCT somehow, but I'm not sure how. Could anyone help me out here?
SELECT m.*
FROM (
SELECT DISTINCT value
FROM mytable
) md
JOIN mytable m
ON m.id =
(
SELECT id
FROM mytable mi
WHERE mi.value = md.value
AND mi.approved = 1
ORDER BY
mi.value DESC, mi.date DESC, mi.id DESC
LIMIT 1
)
Create an index on (value, date, id) for this to work fast.
You need:
select id, value, date, approved where (value, date) in (
select value, max(date)
from your_table
group by value
);
Actually using GROUP BY will yeld better results. try something like this:
SELECT id, value, date, approved FROM table WHERE approved = 1 GROUP BY value ORDER BY date;
select id, value, date, approved
from mytable a
where approved = 1
and date =
(select max(b.date)
from mytable b
where b.approved = 1
and b.value = a.value)
select
id,
value,
date
from
( select
value, max( date ) as LastInstance
from
YourTable
where
approved = 1
group by
value ) PreQuery
join YourTable
on PreQuery.value = YourTable.value
and PreQuery.LastInstance = YourTable.LastInstance
and YourTable.approved = 1
order by
date
Try with this:
SELECT * DISTINCT FROM TABLA WHERE APPROVED = 1 ORDER BY DATE DESC
Hope this helps you.

Query to get distinct ID and random field of it's related field

OK, Here is what my table looks like
------------------------------------------------
Textid type
-----------------------------------------------
1 a
2 b
1 a
1 c
2 c
1 a
3 a
------------------------------------------------
Now, I need a query that can give me this output...
-------------------------------------
Distinct(textid) | rand(type) |
--------------------------------------
1 a
2 c
3 a
--------------------------------------
rand(type) gives me number.... Do I need to pass a different records inside rand() like random(SELECT type FROM mytable)
UPDATE
I am trying to get a distinct id from the table and random field(type) associated with that distinct id
SELECT textid,
(
SELECT type
FROM mytable mi
WHERE mi.textid = md.textid
ORDER BY
RAND()
LIMIT 1
)
FROM (
SELECT DISTINCT textid
FROM mytable
) md
Create a composite index on mytable (textid, type) for this to work fast:
CREATE INDEX ix_mytable_textid_type ON mytable (textid, type)