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.
Related
The following query returns what is displayed in the attached image.
What I thought would be very simple has turned out to be very complex. All I simply want to do is now total up the result into one row and column. In this case the sum would be 161. How do I do this? I've literally tried everything. I hope I've provided enough information.
SELECT
TRUNCATE
(
SUM(
`assignment`.`percentage_achieved` *(
SELECT
`unitComponentWeighting`.`percentage_weighting` / 100
FROM
`unitComponentWeighting`
WHERE
`assignment`.`assignment_component_id` = `unitComponentWeighting`.`component_lookup_id`
LIMIT 1
)
),
2
) AS `unit_percentage_grade`
FROM
`assignment`
LEFT JOIN `assignmentType` ON `assignment`.`assignment_type_id` = `assignmentType`.`id`
LEFT JOIN `assignmentComponentLookup` ON `assignmentComponentLookup`.`id` = `assignment`.`assignment_component_id`
LEFT JOIN `unit` ON `unit`.`id` = `assignment`.`unit_id`
LEFT JOIN `assignmentSequence` ON `assignmentSequence`.`id` = `assignment`.`assignment_sequence_id`
LEFT JOIN `yearGroup` ON `yearGroup`.`id` = `unit`.`year_group_id`
WHERE
`yearGroup`.`id` = 1
GROUP BY
`assignment`.`unit_id`
try removing this part
" GROUP BY
assignment.unit_id "
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
I have the following code and I'm trying to group the messages
Here is a picture of database table and how the groups should be
and here is the SQL statement
SELECT a.* FROM `user_messages` `a`
JOIN (
SELECT `sender`, MAX(`id`) `last_id` FROM `user_messages` WHERE `receiver` = '1' GROUP BY `sender`
) `b`
ON `a`.`sender` = `b`.`sender` AND `a`.`id` = `b`.`last_id`
WHERE `a`.`receiver` = '1'
ORDER BY `id` DESC
OUTPUT:
I want to get somehow the last record where "receiver" is not my id, but "sender" is and name receiver column as "id" or something.
...so what i want is following result:
id | msg
13852 123
48 Hello!
17 321
Here is a fiddle: http://sqlfiddle.com/#!9/e06d57/3/0
To map my generic answer to your particular use case (using example 1):
SELECT receiver AS id, msg
FROM user_messages outerTable
WHERE NOT EXISTS
( SELECT *
FROM user_messages innerTable
WHERE innerTable.sender = outerTable.sender
AND innerTable.receiver = outerTable.receiver
AND innerTable.added > outerTable.added
)
AND sender = 1
This is a very common use case. There are several ways to write this code. Depending on the SQL engine used, they will be of different speeds.
I will use fairly generic column names. Tweak as needed.
SELECT common_id, msg
FROM myTable outerTable
WHERE NOT EXISTS
( SELECT *
FROM myTable innerTable
WHERE innerTable.common_id = outerTable.common_id
AND innerTable.time > outerTable.time
)
Please note that if there are two rows with identical common_id and time columns, then both will show up in the output. You can replace the > with >= to hide both of those rows.
The other common approach is kind of difficult to make sense of, but here goes. Notice the similarities to the NOT EXISTS approach.
SELECT outerTable.common_id, outerTable.msg
FROM myTable outerTable
LEFT JOIN myTable innerTable
ON innerTable.common_id = outerTable.common_id
AND innerTable.time > outerTable.time
WHERE innerTable.common_id IS NULL
According to your description, you seem to want something like this:
select um.receiver as id, um.msg
from user_messages um
where um.sender = 1 and
um.id = (select max(um2.id)
from user_messages um2
where um2.msg = um.msg and um2.receiver <> 1 and um.sender = 1
);
It doesn't produce the desired output, but that is because the output is inconsistent with the text description.
I have the following Database Design:
Database Design
I want to get all Information from table 'info' where the id IS NOT in table 'archived'. To do so I wrote:
SELECT *
FROM traffic_info i
LEFT JOIN
traffic_info_archived a ON (i.info_id = a.info_id)
WHERE
i.branch_id = 4 AND i.user_id = 7 a.info_id IS NULL ORDER BY i.info_date_from ASC
This works as expected.
The next challenge is to only show information that are also included in the 'published' table. To get this done I have expanded my previous query to :
SELECT *
FROM traffic_info i
LEFT JOIN
traffic_info_archived a ON (i.info_id = a.info_id)
RIGHT JOIN
traffic_info_publised p ON (i.info_id = p.info_id)
WHERE
i.branch_id = 4 AND a.info_id AND i.user_id = 7 IS NULL ORDER BY i.info_date_from ASC
This does also work as expected.
The final challenge is to Order this result according to table 'read'. Information´s id that are NOT in table 'read' should be ordered ASC. But even if its id does not appear in table 'read' they should not be excluded from the query output. BUT the primary ORDER should be
i.info_date_from ASC
I hope this is understandable, my English is not the best :) If not, please comment and I will do my best to make it understandable. Hope some can help!
I´ve tried to create a SQLFiddle, but I wasn´t able to create a runnable example, sorry for that.
UPADTE:
Using the approach from #Dylan Su
SELECT *
FROM traffic_info i
LEFT JOIN
traffic_info_archived a ON (i.info_id = a.info_id)
INNER JOIN
traffic_info_publised p ON (i.info_id = p.info_id)
WHERE
i.branch_id = 4 AND a.info_id AND i.user_id = 7 IS NULL
ORDER BY
CASE WHEN NOT EXISTS(SELECT 1 FROM read WHERE i.info_id = read.info_id)
THEN i.info_date_from END ASC;
the goal is nearer then it ever was :)
Sample Data output
Both entries marked with a red "X" are in table read. Therefore id 3 should be last the, in the middle 1 and 2 at the top.
So the last thing to archive is to do the correct order of table read. I´ve tried sth like:
(SELECT 1 FROM traffic_info_read WHERE i.info_id = traffic_info_read.info_id ORDER BY traffic_info_read.info_id DESC)
But that didn´t had any influnce.
Try this:
SELECT *
FROM traffic_info i
LEFT JOIN
traffic_info_archived a ON (i.info_id = a.info_id)
INNER JOIN
traffic_info_publised p ON (i.info_id = p.info_id)
WHERE
i.branch_id = 4 AND a.info_id AND i.user_id = 7 IS NULL
ORDER BY
EXISTS(SELECT 1 FROM read WHERE i.info_id = read.info_id) ASC,
i.info_date_from ASC;
The Answer of #Dylan Su is absolutely correct and I won´t unmark it as accepted.
However, based on the Information I gained from the conversation I have created another solution, that doesn´t make use of sub query.
I heard that using just JOIN´s will result in better performance, I don´t know if it´s correct and I don´t have that much test data currently to find out, but here is the solution using no sub query.
SELECT *
FROM traffic_info i
LEFT JOIN
traffic_info_archived a ON (i.info_id = a.info_id)
INNER JOIN
traffic_info_published p ON (i.info_id = p.info_id)
LEFT JOIN
traffic_info_read r ON (i.info_id = r.info_id)
WHERE
i.branch_id = 4 AND a.info_id IS NULL ORDER BY r.info_id IS NULL DESC, i.info_date_from ASC
;
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