MYSQL - Select selecting rows where another column equals something - mysql

I have this query:
select feature_requests.*,
from feature_requests
where feature_requests.status in ('open','closed','indevelopment')
I also have another status - denied.
I need to also select all rows with status denied but another column on my features request table must equal something.
So something that does this:
select feature_requests.*,
from feature_requests
where feature_requests.status in ('open','closed','indevelopment','denied') and
if status = denied, instance_id = ?
Not sure of the correct syntax. Thanks for any help :)

The WHERE clause is the correct place to put these kind of conditions, but with a few differences:
SELECT `fr`.*
FROM `feature_requests` fr
WHERE (`fr`.`status` IN ('open','closed','indevelopment')) OR
((`fr`.`status` = 'denied') AND (`fr`.`instance_id` = ?))
P.S - Notice I'm using an alias for feature_requests called fr instead of writing the whole name again and again. And You don't have to write its name at all because you're using only one table in your query, but I would still use it because it reduces the chances of future mistakes.
For further reading - SELECT Syntax

From rusty memory, you're probably wanting something like this
SELECT feature_requests.* FROM feature_requests
WHERE feature_requests.status IN ('open', 'closed', 'indevelopment') OR
(feature_requests.status='denied' AND instance_id = ???)
What you have right now is pretty close.
http://www.tutorialspoint.com/sql/sql-and-or-clauses.htm

This should work:
SELECT
feature_requests.*
FROM
feature_requests
WHERE
feature_requests.status IN ('open','closed','indevelopment') OR (
feature_requests.status='denied' AND
instance_id=?
)
This can also be written without listing the table name over and over if it is the only table that you are using like this:
SELECT
*
FROM
feature_requests
WHERE
status IN ('open','closed','indevelopment') OR (
status='denied' AND
instance_id=?
)
When using AND and/or OR in your where clause please also remember to use parenthesis ( ) to show your actual meaning even when you know what takes precedence between the AND and OR. For more information on precedence of operators with MySQl Example:
color=blue AND shape=circle OR type=ball
means
(color=blue AND shape=cirlce) OR type=ball
but could easily be misinterpreted as
color=blue AND (shape=circle OR type=ball)

Related

SELECT * FROM db1 WHERE db1.table.value = db2.table.value

I'm working with mySQL db and trying to display the correct data for the user. In order to do that I check if the data that I call from one backend is equal to username from another backend like so
SELECT * FROM db1 WHERE db1.table.value = db2.table.value
Names of databases are A and B.
SELECT *
FROM `A.onboardings`
, `B.loginsystem`
WHERE onboardings.sales_email = loginsystem.username
The problem is I get an error A.A.onboardings doesn't exists and A.B.loginsystem doesn't exist pls help :(
You must use this form - from A onboardings
You have to put the backticks in the right pace, or else mysql things your table is called A.onboardings
As seen bleow the needs to be around the database and the table name
And the use of aliases helps to keep even in big queries a good overview and yu have to write less
"SELECT * FROM `A`.`onboardings` a1,`B`.`loginsystem` b1 WHERE a1.sales_email = b1.username"
Try this one( Change the query according to your DB name, table, and matching column name)
SELECT * FROM mydatabase1.tblUsers INNER JOIN mydatabase2.tblUsers ON mydatabase1.tblUsers.UserID = mydatabase2.tblUsers.UserID
The problem is that
`A.onboardings`
is not the same as
A.onboardings
The first is a table reference where there table name has a period in it. The second is for the onboardings table in database A.
In addition, you should be using JOIN!!!
SELECT *
FROM A.onboardings o JOIN
B.loginsystem ls
ON o.sales_email = ls.username;
If you feel compelled to escape the identifies -- which I do not recommend -- then:
SELECT *
FROM `A`.`onboardings` o JOIN
`B`.`loginsystem` ls
ON o.sales_email = ls.username;

how to write this query in correct syntax?

SELECT collegename(SELECT allotement.collegename,dean.id
FROM dean,allotement
WHERE allotement.city=dean.city
&&dean.collegename<>allotement.collegename
&&dean.id<>allotement.id)as t WHERE id=1
SELECT collegename from (
SELECT allotement.collegename, dean.id
FROM dean,allotement WHERE allotement.city=dean.city
and dean.collegename<>allotement.collegename
and dean.id<>allotement.id)
as t WHERE id=1
A few points to note here:
Treat sub-query as a table source from which you are retrieving the data. Thus, you need a from in the first line.
&& doesn't work in SQL. You have to write and instead.
In your case, writing as t is optional.
You can actually go through a pretty good link which I generally use to follow mySQL syntax, as it's a bit confusing, considering the fact that different SQL databases have a slight variation in syntax and functions available.
You can refer to the official mySQL docs here as well, if in case required.
TRY THIS: We can simply achieve that in following simple way even we don't need sub query for that:
SELECT a.collegename, d.id
FROM dean AS d
INNER JOIN allotement AS a ON a.city = d.city
AND d.collegename <> a.collegename
AND d.id <> a.id
WHERE d.id = 1

Little bit of trouble with my MySQL query

My MySQL Query
Ok so I'm trying to add another column (leave_remaining) that will display that if the leave_status is 'ok' then the leave_remaining will show the number of leave days that employee has left. I keep getting errors with this. What is the right syntax here? Thank you
This works:
select id,leave_started,leave_ended,no_of_leave_allowed,
leave_ended-leave_started AS no_of_leaves_taken,
if (leave_ended-leave_started >no_of_leave_allowed,
'leave exceeded','ok')as leave_status
from leave_taken;
This does not:
if (leave_status,'ok',
(no_leave_allowed-no_leaves_taken))as leave_remaining
from leave_taken;
select * from leave_taken;
If I'm understanding you properly, I think you want this:
SELECT
id, leave_started, leave_ended, no_of_leave_allowed,
(leave_ended - leave_started) AS no_of_leaves_taken,
IF(
(leave_ended - leave_started) > no_of_leave_allowed,
'leave exceeded',
'ok'
) AS leave_status,
IF (
(leave_ended - leave_started) > no_of_leave_allowed,
(no_of_leave_allowed - (leave_ended - leave_started)),
0
) AS leave_remaining
FROM leave_taken;
Though not sure how you have defined leave_started and leave_ended that you can subtract them like that...
http://sqlfiddle.com/#!9/16cdb3/6
SELECT has to be before the IF, altough you are not doing anything.
The correct statement is
SELECT something as alias, something_else as alias_else, if(,,) as alias_if
FROM table
WHERE where = clause
When you have to use some statement (IF or CASE for example), that result in a field, it has to be inside a select.

Why is this MySQL statement pulling data from both tables on this JOIN?

select * from user_levels
join collectors_users on user_levels.id = collectors_users.user_level
where collectors_users.username = 'testuser'
I want it to pull everything from user_levels and nothing from collectors_users. But it's pulling from both. How do I correct the statement?
Instead of select * specify what you actually want and use select user_levels.* or even better skip the * and write out the columns you want (and consider using aliases to keep it short and tidy): select ul.col1, ul.col2 ... from userlevels ul join ...
It is getting all the data as the '*' means 'all' columns. You can limit the columns for just one table by specifying the table:
select user_levels.*
from user_levels
join collectors_users on user_levels.id = collectors_users.user_level
where collectors_users.username = 'testuser'
Pro tip: Don't use SELECT * in running software. Instead, be as specific as you can be about the columns you want in your result set.
SELECT user_levels.*
should help a bit.
I might suggest that you use in or exists, because this is more consistent with the intention of the query:
select ul.*
from user_levels ul
where ul.id in (select cu.user_level
from collectors_users cu
where cu.username = 'testuser'
);
In addition, this version will not produce duplicate rows if collectors_users has multiple matching rows for a singel row in user_levels.
Also note the use of table aliases: these make the query easier to write and to read.

How to avoid filesort for that mysql query?

I'm using this kind of queries with different parameters :
EXPLAIN SELECT SQL_NO_CACHE `ilan_genel`.`id` , `ilan_genel`.`durum` , `ilan_genel`.`kategori` , `ilan_genel`.`tip` , `ilan_genel`.`ozellik` , `ilan_genel`.`m2` , `ilan_genel`.`fiyat` , `ilan_genel`.`baslik` , `ilan_genel`.`ilce` , `ilan_genel`.`parabirimi` , `ilan_genel`.`tarih` , `kgsim_mahalleler`.`isim` AS mahalle, `kgsim_ilceler`.`isim` AS ilce, (
SELECT `ilanresimler`.`resimlink`
FROM `ilanresimler`
WHERE `ilanresimler`.`ilanid` = `ilan_genel`.`id`
LIMIT 1
) AS resim
FROM (
`ilan_genel`
)
LEFT JOIN `kgsim_ilceler` ON `kgsim_ilceler`.`id` = `ilan_genel`.`ilce`
LEFT JOIN `kgsim_mahalleler` ON `kgsim_mahalleler`.`id` = `ilan_genel`.`mahalle`
WHERE `ilan_genel`.`ilce` = '703'
AND `ilan_genel`.`durum` = '1'
AND `ilan_genel`.`kategori` = '1'
AND `ilan_genel`.`tip` = '9'
ORDER BY `ilan_genel`.`id` DESC
LIMIT 225 , 15
and this is what i get in explain section:
these are the indexes that i already tried to use:
any help will be deeply appreciated what kind of index will be the best option or should i use another table structure ?
You should first simplify your query to understand your problem better. As it appears your problem is constrained to the ilan_gen1 table, the following query would also show you the same symptoms.:
SELECT * from ilan_gene1 WHERE `ilan_genel`.`ilce` = '703'
AND `ilan_genel`.`durum` = '1'
AND `ilan_genel`.`kategori` = '1'
AND `ilan_genel`.`tip` = '9'
So the first thing to do is check that this is the case. If so, the simpler question is simply why does this query require a file sort on 3661 rows. Now the 'hepsi' index sort order is:
ilce->mahelle->durum->kategori->tip->ozelik
I've written it that way to emphasise that it is first sorted on 'ilce', then 'mahelle', then 'durum', etc. Note that your query does not specify the 'mahelle' value. So the best the index can do is lookup on 'ilce'. Now I don't know the heuristics of your data, but the next logical step in debugging this would be:
SELECT * from ilan_gene1 WHERE `ilan_genel`.`ilce` = '703'`
Does this return 3661 rows?
If so, you should be able to see what is happening. The database is using the hepsi index, to the best of it's ability, getting 3661 rows back then sorting those rows in order to eliminate values according to the other criteria (i.e. 'durum', 'kategori', 'tip').
The key point here is that if data is sorted by A, B, C in that order and B is not specified, then the best logical thing that can be done is: first a look up on A then a filter on the remaining values against C. In this case, that filter is performed via a file sort.
Possible solutions
Supply 'mahelle' (B) in your query.
Add a new index on 'ilan_gene1' that doesn't require 'mahelle', i.e. A->C->D...
Another tip
In case I have misdiagnosed your problem (easy to do when I don't have your system to test against), the important thing here is the approach to solving the problem. In particular, how to break a complicated query into a simpler query that produces the same behaviour, until you get to a very simple SELECT statement that demonstrates the problem. At this point, the answer is usually much clearer.