im not sure if im doing well with this field calendar.type_event = NULL. Now works well to me because I need to differentiate the second SELECT as a third type.
I want to do something like calendar.type_event = 'shared_event' to differentiate it. But returns a 0, with NULL returns nothing. This is not the problem only I need to know if I can assign my own value: 'shared_event'.
Thanks a lot
The entire query is:
(SELECT
id, type_event
FROM calendar
WHERE user_id = '.$user_id.'
)
UNION
(SELECT
calendar.id, calendar.type_event = NULL
FROM calendar
RIGHT JOIN avisos ON avisos.app_id = calendar.id
WHERE avisos.user_destiny_id = '.$user_id.'
)
ORDER BY fecha_evento ASC
I need to know if I can assign my own value: 'shared_event'.
Yes, you can. In place of column calendar.type_event just use literal 'shared_event'
Example:
SELECT
calendar.id, 'shared_event'
FROM calendar
RIGHT JOIN avisos ON avisos.app_id = calendar.id
WHERE avisos.user_destiny_id = '.$user_id.'
You should be able to do something like this:
(SELECT
id, type_event
FROM calendar
WHERE user_id = '.$user_id.'
)
UNION
(SELECT
calendar.id, "shared_event"
FROM calendar
RIGHT JOIN avisos ON avisos.app_id = calendar.id
WHERE avisos.user_destiny_id = '.$user_id.'
)
ORDER BY fecha_evento ASC
I think this is what you are looking for:
(SELECT
id, type_event
FROM calendar
WHERE user_id = '.$user_id.'
)
UNION
(SELECT
calendar.id, '' type_event
FROM calendar
RIGHT JOIN avisos ON avisos.app_id = calendar.id
WHERE avisos.user_destiny_id = '.$user_id.'
)
ORDER BY fecha_evento ASC
In the second query, type_event field will contain null values. If the type_event field is a numeric field, you can put 0 (ZERO) instead of '' (empty single quotes/string).
Related
I want to use mysql's "JOIN"
I want to group rows by "date_text" where "tokenIdx" is "1001" and "datetime_unix" is the highest value.
Is my code wrong?
SELECT `A.idx`
FROM `data_candle_h1` 'A'
JOIN
(
SELECT `date_text`, MAX(`datetime_unix`) AS 'datetime_unix'
FROM `data_candle_h1`
WHERE `tokenIdx` = '1002'
GROUP BY `date_text`
) 'B'
ON `A.datetime_unix` = `B.datetime_unix`
WHERE `A.tokenIdx` = '1002'
Your query is syntactically perfect. Just remove single quotes('') around table aliases (A and B). I have corrected it. Please check this out.
SELECT `A.idx`
FROM `data_candle_h1` A
JOIN
(
SELECT `date_text`, MAX(`datetime_unix`) AS 'datetime_unix'
FROM `data_candle_h1`
WHERE `tokenIdx` = '1002'
GROUP BY `date_text`
) B
ON `A.datetime_unix` = `B.datetime_unix`
WHERE `A.tokenIdx` = '1002'
I need to set "dph" in this table "Strobjednavka", but i don´t know whats wrong there. Please help :).
Here is my SQL script:
UPDATE STRObjednavka as o SET dph = (
SELECT dph FROM STRCena WHERE
menuKodCode =
(SELECT menuKodCode FROM STRMenu WHERE
id = o.menuId
)
AND
skupinaId =
(SELECT stravGroupId FROM grups1 WHERE
PKey =
(SELECT SGroup FROM users1 WHERE
PKey = o.userId
)))
WHERE o.price > 0 AND `date` > '2015-01-28 13:52:36' AND dph = 0;
SQL say : SQL error 1242: Subquery returns more than 1 row
You can able to update with below script, but you need to check whether update is correct or not, If you give some sample data then it will be easy to track the problem.
UPDATE STRObjednavka as o SET dph = (
SELECT max(dph) FROM STRCena WHERE
menuKodCode =
(SELECT max(menuKodCode) FROM STRMenu WHERE
id = o.menuId
)
AND
skupinaId =
(SELECT max(stravGroupId) FROM grups1 WHERE
PKey =
(SELECT max(SGroup) FROM users1 WHERE
PKey = o.userId
)))
WHERE o.price > 0 AND `date` > '2015-01-28 13:52:36' AND dph = 0;
Unfortunately, MySQL doesn't allow you to LIMIT a subquery. Depending on your use case you can add MIN or MAX to your subqueries. Here it is with MINs in all the subqueries:
UPDATE STRObjednavka as o SET dph = (
SELECT MIN(dph) FROM STRCena WHERE
menuKodCode =
(SELECT MIN(menuKodCode) FROM STRMenu WHERE
id = o.menuId
)
AND
skupinaId =
(SELECT MIN(stravGroupId) FROM grups1 WHERE
PKey =
(SELECT MIN(SGroup) FROM users1 WHERE
PKey = o.userId
)))
WHERE o.price > 0 AND `date` > '2015-01-28 13:52:36' AND dph = 0;
Although you really only need to add it to the subquery that's returning more than one row.
Your first problem is that you're writing '.... = (SELECT .... )'. Since you're using the equality operator, you're asking SQL to assign an entire column of values to a single cell. Change your equality operators before your subqueries to IN operators.
You probably should use a different query pattern.
You have this sort of thing in your query, in several places.
WHERE menuKodCode = /* !! might generate error 1242 */
(SELECT menuKodCode FROM STRMenu WHERE id = o.menuId)
There's no guarantee that your inner query won't return more than one row, and when it does, MySQL throws error 1242.
SQL works wiith sets of values. If you used IN instead of =, your query would work.
WHERE ... menuKodCode IN
(SELECT menuKodCode FROM STRMenu WHERE id = o.menuId)
But you should figure out whether that logic is correct. If I were you I'd do a whole bunch of SELECT operations to test it before doing UPDATE.
am new here so please redirect me if am posting this wrong
sorry i can't post images yet
I have this table , I want to select all where type = 'Maladie'
but ... if a row with type = 'Reprise' that contains a date between any of the maladie type ones then i must show
maladie row date start -> Reprise rows date start
instead of
maladie row date start -> maladie row date end
so result for that image would look like this
note: rows with type Reprise may or may not exist
thnks
Outer join the reprise records. Where you find a match use its dates, where you don't use the original dates:
select
m.mat,
m.start,
coalesce(r.end, m.end) as end,
m.number_days,
m.number_hours
from (select * from mytable where type = 'Maladie') m
left join (select * from mytable where type = 'Reprise') r
on r.mat = m.mat and r.start between m.start and m.end;
If there can be more than one reprise record per maladie date range and you want to take the first one then, use:
select
m.mat,
m.start,
coalesce(r.repday, m.end) as end,
m.number_days,
m.number_hours
from (select * from mytable where type = 'Maladie') m
left join
(
select mat, min(end) as repday
from mytable
where type = 'Reprise'
group by mat
) r on r.mat = m.mat and r.repday between m.start and m.end;
You need to create self join and filter type that use min to catch first date if there is more that one reprise
SELECT a.mat
,a.start
,min(coalesce(b.END, a.END)) AS END
,a.number_of_days
,a.number_of_hours
,type
FROM table1 a
LEFT JOIN (
SELECT mat
,start AS start
,END AS END
FROM table1 t
WHERE t.type = 'Reprise'
) b ON b.start BETWEEN a.start
AND a.END and a.mat=b.mat
WHERE type = 'Malaide'
GROUP BY a.mat
,a.start
ORDER BY start
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.
We have a nested sql query we want to group by a field that is into a nested query rather than grouping by a field that is on the main query .
SELECT dataissue.value as a,
COUNT(value),
substring(issue.entry, 1, 3)
FROM DataIssue, issue
WHERE field = 'point_d_effort'
AND dataissue.issue = issue.id
AND issue IN (
SELECT issue
FROM dataissue, issue
WHERE dataissue.issue = issue.id
AND value = 'récit'
AND substring(issue.entry,1,3) = 'ema'
)
AND issue IN (
SELECT issue
FROM dataissue, issue
WHERE dataissue.issue = issue.id
AND value = 'Fermée'
AND substring(issue.entry,1,3) = 'ema'
)
AND issue IN (
SELECT issue
FROM dataissue, issue
WHERE dataissue.issue = issue.id
AND field = 'version(s)_corrigée(s)' AS b
AND substring(issue.entry,1,3) = 'ema'
)
GROUP BY dataissue.value as b
To sumarize: The group by uses the field value alias a inside the main query WHERE field = 'point_d_effort'. However, I want to group by the field ( value alias b ) inside the nested query WHERE field = 'Version(s)_corrigée(s)'.
How may I do that? Thank you.
For more precisions ,
Hi all first of all , i want to thank you for contributing to the answer here is an SQL fiddle
http://sqlfiddle.com/#!9/610e7/1
-- This query will return all the attributes of an issue
select * from dataissue where issue = '25998' .
What I want to have is :
sum(value) count(value)
where field = 'version(s)_corrigée(s)'
and value = 'Fermée'
and field = 'point_d_effort'
and value = 'récit'
and group it by value where field = 'version(s)_corrigée(s)'
SELECT main2.value AS VALUE,nbreticket,ticket FROM
(
SELECT dataissue.issue,dataissue.value,COUNT(VALUE) AS nbreticket,SUM(VALUE) AS ticket,SUBSTRING(issue.entry,1,3) ,FIELD
FROM DataIssue,issue WHERE dataissue.issue = issue.id AND VALUE IS NOT NULL AND FIELD = 'point_d_effort' AND issue IN ( SELECT issue
FROM dataissue,issue WHERE dataissue.issue = issue.id AND VALUE = 'récit'
AND SUBSTRING(issue.entry,1,3) = 'ema' ) AND issue IN ( SELECT issue
FROM dataissue,issue WHERE dataissue.issue = issue.id AND VALUE = 'Fermée'
AND SUBSTRING(issue.entry,1,3) = 'ema' ) AND issue IN ( SELECT issue
FROM dataissue,issue WHERE dataissue.issue = issue.id
AND FIELD = 'version(s)_corrigée(s)' AND SUBSTRING(issue.entry,1,3) = 'ema' )
GROUP BY dataissue.value, issue
) main1 JOIN
(
SELECT issue, `value` FROM DataIssue WHERE
FIELD = 'version(s)_corrigée(s)'
)main2
WHERE main1.issue = main2.issue
GROUP BY main2.value
In your sql GROUP BY clause has alias name, we can't do alias name for group clause.
Again in where condition has alias name, we can't do alias name for where clause also.
In your sql some syntax error is there. I cleared all errors now sql is running fine.
Thank you.