Mysql check if row exists in regular select? - mysql

I got an question about mysql. Is it possible to check if an row exists in an external table?
For example, I need to show recent uploaded images and I would like to show some userdata with it and show if the user is online.
My current query is:
SELECT `users`.`username`, `users`.`location`, `users`.`age`, `users`.`dateofbirth`
FROM (`images`)
JOIN `users`
ON `users`.`userid` = `images`.`userid`
WHERE `images`.`active` = 1
LIMIT 12
But I'm missing the 'is online' part. Is it possible to use this in the select? For example if the row exists there would be a value in the select named online and it's value = 1 and if user is not online (no row in table) the value needs to be 0. Is that possible?

Seems like you just need to use a LEFT JOIN on the other table and then a CASE to provide the value:
SELECT `users`.`username`,
`users`.`location`,
`users`.`age`,
`users`.`dateofbirth`,
case when o.`userid` is null then 0 else 1 end UserOnline
FROM (`images`)
JOIN `users`
ON `users`.`userid` = `images`.`userid`
left join online_table o
on `users`.`userid` = o.`userid`
WHERE `images`.`active` = 1
LIMIT 12

Related

MySQL query for not exists in another table

I have two MySQL Tables...
1. master_fee
2. fees_receiving_ledger
I do not want to show the FeeId containing FeeFrequencyId : 4 from master_fee table if they are present in fees_receiving_ledger table.
Like above I do not want to show the Admission Fee (FeeId:1) containing FrequencyId : 4 as it is present in fees_receiving_ledger.
I have tried like below...
Select
master_fee.*
From
master_fee
Where Not Exists(Select
fees_receiving_ledger.FeeId
From
fees_receiving_ledger
Where
fees_receiving_ledger.FrequencyId = '4')
My query giving me blank result.
I tried This but failed.
What should be the query ?
I am using VB.NET with MySQL database.
you forgot the join condition in your subselect.
select m.* from master_fee m
where not exists (
select 1 from
fees_receiving_ledger f
where f.frequencyID = 4
and m.feeid=f.feeid)
You could also do:
select m.* from master_fee m left join fees_receiving_ledger f
on f.feeid = m.feeID
where f.frequencyID <> 4;

MySQL How to deal with Error: Subquery returns more than 1 row?

I'm trying to write a query where it selects all records from a table where certain complex/nested criteria are met. The logic in my query I think is correct, but the problem I'm running into is the final subquery (see example) is returning more than 1 row, which is what I would expect/need. So, the problem is, how do I deal with this? Does MySQL support some kind of looping or set criterion?
SELECT c.primary_key
FROM esjp_content c
WHERE template_id = (
SELECT DISTINCT esjp_content.template_id
FROM esjp_content
INNER JOIN esjp_hw_config ON esjp_content.template_id = esjp_hw_config.proc_id
INNER JOIN esjp_assets ON esjp_hw_config.primary_key = esjp_assets.hw_config_id
WHERE
esjp_content.summary_id > 0
AND
(esjp_assets.asset_label='C001498500' OR esjp_assets.asset_label='H0065' OR esjp_assets.asset_label='L0009')
)
AND
EXISTS (SELECT 1 FROM esjp_content c2 WHERE c2.summary_id = c.primary_key)
AND
c.primary_key != (
/* This subquery returns more than 1 result. */
SELECT esjp_signoffs.content_id
FROM esjp_signoffs
INNER JOIN esjp_assets ON esjp_signoffs.asset_id = esjp_assets.primary_key
WHERE
esjp_signoffs.user_id=1
AND
(esjp_assets.asset_label='C001498500' OR esjp_assets.asset_label='H0065' OR esjp_assets.asset_label='L0009')
);
For additional details on my tables, see this other StackOverflow post I made earlier today. (This is an entirely different question.)
If i understan correctly the
c.primary_key != (
/* This subquery returns more than 1 result. */
SELECT esjp_signoffs.content_id
FROM esjp_signoffs
INNER JOIN esjp_assets ON esjp_signoffs.asset_id = esjp_assets.primary_key
WHERE
esjp_signoffs.user_id=1
AND
(esjp_assets.asset_label='C001498500' OR esjp_assets.asset_label='H0065' OR esjp_assets.asset_label='L0009')
);
return more then a row .. you could use not in ..
c.primary_key not in (
or
inner join ( ..... ) t on c.primary_key != t.the_column_you_need

My SQL query showing error : : #1242 - Subquery returns more than 1 row

I have a problem regarding mysql.
I have few tables like tbl_follow, tbl_user, tbl_post_like,
Now what I want is that my query should return the result like:
i want userid, username, user image, user state from one table->tbl_user,
then i want those users who are following other friend(other user) only if the column "estatus" in table "tbl_follow" contain value as "Active" otherwise if there is an "inactive" value then it should return 0 as i have coded in query.
tbl_follow : 1.iFollowID, 2.iUserID, 3. iFriendID, 4. eStatus
tbl_post_like: 1. iPostLikeID, 2. iUserID, 3. iPostID
tbl_user: 1.iUserID, 2. vUsername, 3. vImage, 4. vState
Now the simple query I am using is:
SELECT u.iUserID,
u.vUsername,
u.vState,
u.vImage,
(SELECT IF(
(SELECT iFollowID
FROM tbl_follow
WHERE iUserID =249
AND iFriendID = 250
AND eStatus = 'Active')!='', 1,0)
FROM tbl_follow) AS is_follow
FROM tbl_user u
INNER JOIN tbl_post_like l ON u.iUserID=l.iUserID
WHERE l.iPostID=21
Not sure about performance on this in comparison to using an additional join, but hopefully it'll work:
Try:
SELECT u.iUserID,
u.vUsername,
u.vState,
u.vImage,
IF(EXISTS
(SELECT iFollowID
FROM tbl_follow
WHERE iUserID =249
AND iFriendID = 250
AND eStatus = 'Active'), 1,0) AS is_follow
FROM tbl_user u
INNER JOIN tbl_post_like l ON u.iUserID=l.iUserID
WHERE l.iPostID=21

MySQL How to check if an value is already in the results?

I've got a complicated problem.
How can I force MySQL to replace the first "command.deagle2" (Mode 1) with the second "command.deagle2" (Mode 0) ?
I simply show you the code and I hope you can help me.
Here my code:
SELECT DISTINCT
`right`.`name` AS `Right`,
1 AS `Mode`
FROM
`user`
INNER JOIN
`user_group` ON
`user`.`id` = `user_group`.`user_id`
INNER JOIN
`group` ON
`user_group`.`group_id` = `group`.`id`
INNER JOIN
`group_right` ON
`group`.`id` = `group_right`.`group_id`
INNER JOIN
`right` ON
`group_right`.`right_id` = `right`.`id`
WHERE
`user`.`username` = 'Dominik'
UNION
SELECT DISTINCT
`right`.`name` AS `Right`,
`user_right`.`mode` AS `Mode`
FROM
`user`,
`right`,
`user_right`
WHERE
`user`.`id` = `user_right`.`user_id` AND
`right`.`id` = `user_right`.`right_id` AND
`user`.`username` = 'Dominik'
This query returns the following results:
Right | Mode
-----------------------
command.deagle | 1
command.deagle2 | 1
command.gmx | 1
command.givegun | 1
command.deagle2 | 0
Sample dataset: http://pastebin.com/m5LHsDRi
I already saw that there is an REPLACE keyword, but I dont really know how to use it properly.
Thanks for your Time.
Dominik
I take it your "mode" column constitutes a priority, and you want the only the distinct value of "Right" with the lowest-numbered priority in your result set.
Try wrapping this query around the query you gave us:
SELECT Right,
MIN(Mode) AS Mode,
FROM (
/* your big query */
) AS q
GROUP BY Right
That will give you what you want. By the way, you can remove the DISTINCT keyword from your main query if you do this; the GROUP BY will fill the same purpose.

MySQL Database design advice - using joins

I am building an AJAX like search page which allows a customer to select a number filters that will narrow down the search. For instance, a user has selected an 'iPhone 5' and has additional filters for capacity (32GB, 64GB) & colour (black, white..).
The user can only select a single radio box per category (so they could select 32GB & Black).. but they could not select (32GB & 64GB & black as two of these belong to the 'capacity' category).
I have added the schema here on sqlfiddle (please ignore the fact i've removed the primary keys they exist in the proper app they have just been removed along with some other fields/data to minimise the sqlfiddle)
http://sqlfiddle.com/#!2/964425
Can anyone suggest the best way to create the query to do the following:
Get all the prices for device_id '2939' (iPhone 5) which has the 'attributes' of '32GB' AND 'Black'
I currently have this - but this only works when selecting for a single attribute:
// search for device with '64GB' & 'Black' attributes (this currently doesn't return any rows)
SELECT `prices`.*
FROM (`prices`)
LEFT JOIN `prices_attributes` ON `prices_attributes`.`price_id` = `prices`.`id`
WHERE `prices`.`device_id` = '2939'
AND `attribute_option_id` = '19'
AND `attribute_option_id` = '47';
// search for device with '64GB' attribute only (this currently DOES return a row)
SELECT `prices`.*
FROM (`prices`)
LEFT JOIN `prices_attributes` ON `prices_attributes`.`price_id` = `prices`.`id`
WHERE `prices`.`device_id` = '2939'
AND `attribute_option_id` = '19';
Any advice on the database design would be appreciated too
Note: I was thinking to have a new column within the 'prices' table that has the matching attribute_ids serialised - would this be not good for optimisation however (e.g would it be slower than the current method)
Since attribute_option_id is an atomic value, it cannot have two different values for the same row. So your WHERE clause cannot match any record:
SELECT `prices`.*
FROM (`prices`)
LEFT JOIN `prices_attributes` ON `prices_attributes`.`price_id` = `prices`.`id`
WHERE `prices`.`device_id` = '2939'
AND `attribute_option_id` = '19' # Here for one row, attribute_option_id is either 19
AND `attribute_option_id` = '47'; # of '47'. Cannot be the both
Instead of JOIN, you could try a subquery if you feel that is more readable. I think MySQL allow that syntax:
SELECT `prices`.*
FROM `prices`
WHERE `prices`.`device_id` = '2939'
AND EXISTS (SELECT *
FROM prices_attributes
WHERE price_id = `prices`.`id`
AND attribute_option_id IN ('19', '47') )
I don't know how MySQL will optimize the above solution. An alternative would be:
SELECT `prices`.*
FROM `prices`
WHERE `prices`.`id` IN (
SELECT DISTINCT `price_id`
FROM prices_attributes
WHERE attribute_option_id IN ('19', '47')
)
I think you should use the IN operator for the attribute_option_id and you set the values dynamically to the query; Also, using group_by you have only one row per price so in effect you get all the prices. Apart from this, the design is ok.
Here, I have made an example:
SELECT `prices`.*
FROM (`prices`)
LEFT JOIN `prices_attributes` ON `prices_attributes`.`price_id` = `prices`.`id`
WHERE `prices`.`device_id` = '2939'
and `attribute_option_id` in ('19','47')
group by `prices`.`device_id`, `prices`.`price`;
Here, you can also add an order clause to order by price:
order by `prices`.`price` desc;
Another way to solve this would be to use a distinct on price, like this:
select distinct(prices.price)
from prices
where prices.device_id = 2939
and id in (select price_id from prices_attributes where attribute_option_id in (19,47));
Join against the devices_attributes_options table several times, once for each attribute the item must have
Something like this:-
SELECT *
FROM devices a
INNER JOIN prices b ON a.id = b.device_id
INNER JOIN prices_attributes c ON b.id = c.price_id
INNER JOIN devices_attributes_options d ON c.attribute_option_id = d.id AND d.attribute_value = '32GB'
INNER JOIN devices_attributes_options e ON c.attribute_option_id = e.id AND e.attribute_value = 'Black'
WHERE a.id = 2939
As to putting serialised details into a field, this is a really bad idea and would come back to bite you in the future!
SELECT * FROM prices WHERE device_id=2939 AND id IN (SELECT price_id FROM prices_attributes WHERE attribute_option_id IN (19,47));
Is it what you're looking for?
EDIT: sorry, didn't notice you're asking for query using joins