Is there a way to get value from a subquery in where inside select?
stop_link Table
id | duid | domain_id
1 | 1 | 1
2 | 2 | 1
3 | 1 | 2
4 | 2 | 2
5 | 3 | 1
Result that I want (assume domain_id = 2)
duid | domain_id
3 | 2
Query (not working):
INSERT INTO stop_link (
duid,
domain_id)
SELECT
IFNULL(MAX(sl.duid), 0) + 1 AS duid,
sl.domain_id
FROM
stop_link sl
WHERE sl.domain_id = (SELECT sd.id FROM stop_domain sd LIMIT 1)
Query working but I wish to avoid the Set Variable:
SET #domain_id = (SELECT sd.id FROM stop_domain sd LIMIT 1);
SELECT
IFNULL(MAX(sl.duid), 0) + 1 AS duid
, #domain_id
FROM
stop_link sl
WHERE sl.domain_id = #domain_id;
Do you mean something like this:
/*Your example Table*/
DECLARE #T
TABLE(ID INT,duid INT,domain_id INT)
INSERT INTO #T
VALUES
(1 , 1 , 1 ),
(2 , 2 , 1),
(3 , 1 , 2),
(4 , 2 , 2),
(5 , 3 , 1)
--The query
SELECT domain_id,Isnull(max(duid),0)+1 [newId]
FROM #T
GROUP BY domain_id
No need of max():
SELECT
IFNULL(sl.duid, 0) + 1 AS duid,
sl.domain_id
FROM
stop_link sl
WHERE sl.domain_id = (SELECT sd.id FROM stop_domain sd LIMIT 1)
ORDER by sl.id DESC
LIMIT 1
Changed answer based on new info from the comments. It sounds like you've got only_full_group_by enabled in your sql_mode. Your query would probably work with that disabled, but the following may also work for you:
INSERT INTO stop_link (
duid,
domain_id)
SELECT
IFNULL(MAX(sl.duid), 0) + 1 AS duid,
sl.domain_id
FROM
stop_link sl
WHERE sl.domain_id = (SELECT sd.id FROM stop_domain sd LIMIT 1)
-- ORDER by sl.domain_id DESC LIMIT 1 # Removed in favor of the following line
GROUP BY sl.domain_id HAVING MAX(sl.id)
;
Note that the subquery may not be returning the stop_domain.id that you want it to be -- you might have intended to select MAX(sd.id), or perhaps you just removed a WHERE sd.url='foo' for clarity's sake.
Related
I have no Idea how to google this stuff so i hope someone can help.
Table: PlayerMoves
HandNr | PlayerName | move | amount | OrderOfExecution
---+----------------+------+--------+-----------------
1 | Hans |raises|
1 | Hans |raises|
1 | Peter |raises|
1 | Hans |raises|
1 | Peter |folds |
Table: PlayersInTheHand
HandNr | Betround
-------+------------
1 | Preflop
SELECT STATEMENT1
Select playermoves.PlayerName,Count(playermoves.move)
FROM playersinthehand,playermoves
WHERE playersinthehand.Betround= 'Preflop' and
playersinthehand.handnr = playermoves.Nr
GROUP BY playermoves.PlayerName;
SELECT RESULT
PlayerName| Betround
-------+------------
Hans | 3
Peter | 2
SELECT STATEMENT2
Select playermoves.PlayerName,Count(playermoves.move)
FROM playersinthehand,playermoves
WHERE playersinthehand.Betround= 'Preflop' AND
playermoves.move = 'raises' or playermoves.move = 'calls'
or playermoves.move = 'bets' and
playersinthehand.handnr = playermoves.Nr
GROUP BY playermoves.PlayerName;
SELECT RESULT
PlayerName| Betround
-------+------------
Hans | 3
Peter | 1
My expected Results should be (Count from Statement 2 divided by Count from Statement 1) *100
EXPECTED RESULT
PlayerName| Betround
-------+------------
Hans | (3/3)*100 = 100%
Peter | (1/2)*100 = 50%
You can do conditional counting using SUM(CASE WHEN <predicate> THEN 1 ELSE 0 END).
For example:
SELECT
playermoves.PlayerName,
100.0 *
sum(case when playersinthehand.Betround = 'Preflop' AND
playermoves.move = 'raises' or playermoves.move = 'calls' then 1 else 0 end
) /
count(playermoves.move) as betround
FROM playersinthehand
join playermoves on playersinthehand.handnr = playermoves.Nr
WHERE playersinthehand.Betround= 'Preflop'
GROUP BY playermoves.PlayerName;
Result:
PlayerName betround
----------- ---------
Hans 100.00000
Peter 50.00000
See running example at DB Fiddle.
Try this. Maybe worth checking if you really need a join or just an 'exists'.
-- Auxiliary data for testing purposes
with PlayerMoves (handnr, playername, move) as(
select 1, 'Hans','raises'from dual union all
select 1, 'Hans','raises' from dual union all
select 1, 'Peter','raises' from dual union all
select 1, 'Hans','raises' from dual union all
select 1, 'Peter','folds' from dual),
PlayersInTheHand (handnr, betround) as(
select 1, 'Preflop ' from dual)
--Actual query
SELECT
playername,
round(SUM(
CASE
WHEN move = 'raises' THEN
1
END
) / COUNT(1) * 100, 2) betround
FROM
playermoves pm
WHERE
EXISTS (
SELECT
null
FROM
playersinthehand ph
WHERE
ph.handnr = pm.handnr
AND ph.betround = 'Preflop'
)
GROUP BY
playername;
Here is my MySQL query with its result, I want to obtain for each value of 'function' the first result of 'priority', and thus get the result below
However, a syntax of the type "SELECT function, FIRST (priority) ... GROUP BY function" does not exist, do you have any idea how to do this?
SELECT
function,
priority
FROM challenge_access_rule
WHERE 10 = challenge_access_rule.challenge_id
AND (
rule = 'everybody'
OR (rule = 'friends' AND 1)
)
UNION
SELECT
function,
isRestriction AS priority
FROM challenge_access_user
WHERE 10 = challenge_access_user.challenge_id AND challenge_access_user.user_id = 2
ORDER BY ABS(priority)
-- RESULT --
emitInstance | 0
emitDeal | 0
emitDealInstance | 1
emitDeal | 100
emitDealInstance | -100
vote | -100
emitDeal | -200
view | -200
interact | -200
-- DESIRED RESULT --
emitInstance | 0
emitDeal | 0
emitDealInstance | 1
vote | -100
view | -200
interact | -200
Thanks,
Bastien
First, I would simplify your current query to:
SELECT car.function, car.priority
FROM challenge_access_rule car
WHERE 10 = car.challenge_id AND
( car.rule in ('everybody', 'friends') or
car.user_id = 2
)
ORDER BY ABS(car.priority);
Then, if you want the minimum of the absolute value of the priority, then you can use aggregation and a substring_index()/group_concat() trick:
SELECT car.function,
substring_index(group_concat(car.priority order by ABS(car.priority)), ',', 1) as priority
FROM challenge_access_rule car
WHERE 10 = car.challenge_id AND
( car.rule in ('everybody', 'friends') or
car.user_id = 2
)
GROUP BY car.function;
or a case expression:
SELECT car.function,
(case when min(car.priority) = - min(abs(car.priority))
then - min(abs(car.priority))
else min(car.priority)
end) as priority
FROM challenge_access_rule car
WHERE 10 = car.challenge_id AND
( car.rule in ('everybody', 'friends') or
car.user_id = 2
)
GROUP BY car.function;
This code work !
Thanks to Gordon
SELECT function,
substring_index(group_concat(priority ORDER BY ABS(priority)), ',', 1)
FROM (
SELECT
function,
priority
FROM challenge_access_rule
WHERE 10 = challenge_access_rule.challenge_id
AND (
rule = 'everybody'
OR (rule = 'friends' AND 1) -- 'AND 1' edit after
)
UNION
SELECT
function,
isRestriction AS priority
FROM challenge_access_user
WHERE 10 = challenge_access_user.challenge_id AND challenge_access_user.user_id = 2
ORDER BY ABS(priority)
) AS toto
GROUP BY function
When executing below query
SELECT `game_turns`.`in_darts`, `game_turns`.`date`, MAX(game_turns.score) AS max_score
FROM `game_turns`
JOIN `games` ON `games`.`id` = `game_turns`.`game_id` AND `games`.`training` = 1
WHERE `game_turns`.`uid` = 2
AND `game_turns`.`out` = 1
AND `game_turns`.`in_darts` = 3
ORDER BY `game_turns`.`score` DESC
LIMIT 1
I get the max score for that user id (uid) and out in 3 darts, but the rest (date) is wrong.
Fields are
Score Uid GameID Score out in_darts date
121 2 4 8 1 3 2015-07-21 13:52:12
8465 2 142 100 1 3 2015-09-05 19:46:29
It returns the score 100 from row ID 8465 but the rest is from row ID 121
I have googled it and came on some Stackoverflow results saying that I should use ORDER BY and LIMIT 1, but looks like it aint working for me.
Order by Date also didn't do the trick.
A simple order by and limit should do what you want:
SELECT gt.`in_darts`, gt.`date`, gt.score
FROM `game_turns` gt JOIN
`games` g
ON g.`id` = gt.`game_id` AND g.`training` = 1
WHERE gt.`uid` = 2 AND gt.`out` = 1 AND gt.`in_darts` = 3
ORDER BY gt.`score` DESC
LIMIT 1;
There is no need for aggregation.
If seeking a solution that would work for multiple UID's then aggregation becomes useful - via a subquery.
SQL Fiddle
MySQL 5.6 Schema Setup:
CREATE TABLE Table1
(`Score_A` int, `Uid` int, `GameID` int, `Score_B` int, `out` int, `in_darts` int, `date` datetime)
;
INSERT INTO Table1
(`Score_A`, `Uid`, `GameID`, `Score_B`, `out`, `in_darts`, `date`)
VALUES
(121, 2, 4, 8, 1, 3, '2015-07-21 13:52:12'),
(8465, 2, 142, 100, 1, 3, '2015-09-05 19:46:29')
;
Query 1:
SELECT
t.*
FROM table1 t
INNER JOIN (
SELECT Uid, max(Score_B) as Score_B
FROM table1
GROUP BY uid
) msb ON t.Uid = msb.Uid and t.Score_B = msb.Score_B
Results:
| Score_A | Uid | GameID | Score_B | out | in_darts | date |
|---------|-----|--------|---------|-----|----------|-----------------------------|
| 8465 | 2 | 142 | 100 | 1 | 3 | September, 05 2015 19:46:29 |
I have a table [dbo].[RISK_DISCPLN]
RISK_DISCPLN_ID RISK_DISCPLN_NM
1 LegalRisk
2 institutional Risk
4 Market Risk
Tabbe Name [dbo].[PROJ_RISK_DISCPLN]
PROJ_ID RISK_DISCPLN_ID
1 1
1 2
1 4
2 1
2 2
2 4
3 1
3 2
3 4
Table Name [dbo].[USER]
USER_ID USER_FIRST_NM USER_LST_NM
2 saravanakumar rajkumar
3 Soosai Antony
4 Adam Allen
5 Babita Tripathy
9 stacey Davis
11 NULL NULL
I tried below query to display names into the corresponding risk, i am getting all the names as null value... Help needed please
;with cte as
(
SELECT [PROJ_RISK_DISCPLN].PROJ_ID,
[USER].USER_LST_NM + ' '+ [USER].USER_FIRST_NM as Name,
[RISK_DISCPLN].RISK_DISCPLN_NM,
[RISK_DISCPLN].RISK_DISCPLN_ID,
[USER].[USER_ID]
FROM dbo.[PROJ_RISK_DISCPLN]
left join [dbo].[USER]
on [PROJ_RISK_DISCPLN].RISK_OWN_USER_ID = [dbo].[USER].[USER_ID]
left join dbo.[RISK_DISCPLN] on
[PROJ_RISK_DISCPLN].RISK_DISCPLN_ID = [RISK_DISCPLN].RISK_DISCPLN_ID
)
select *
from
(
select c1.PROJ_ID,
c1.RISK_DISCPLN_NM,
STUFF(
(SELECT ', ' + c2.Name
FROM cte c2
where c1.PROJ_ID = c2.PROJ_ID
and c1.RISK_DISCPLN_ID = c2.RISK_DISCPLN_ID
FOR XML PATH (''))
, 1, 1, '') AS Name
from cte c1
) d
pivot
(
max(Name)
for RISK_DISCPLN_NM in ([LegalRisk Owner],[institutional Risk Owner],[Market Risk Owner])
) piv
I got answer, Instead [LegalRisk Owner],[institutional Risk Owner],[Market Risk Owner]
i have to use [LegalRisk],[institutional Risk],[Market Risk] ....
I have seen this issue in SF, but me being a noob I just can't get my fried brain around them. So please forgive me if this feels like repetition.
My Sample Table
--------------------------
ID | Supplier | QTY
--------------------------
1 1 2
2 1 2
3 2 5
4 3 2
5 1 3
6 2 4
I need to get the rows "UNTIL" the cumulative total for "QTY" is equal or greater than 5 in descending order for a particular supplier id.
In this example, for supplier 1, it will be rows with the ids of 5 and 2.
Id - unique primary key
Supplier - foreign key, there is another table for supplier info.
Qty - double
It ain't pretty, but I think this does it and maybe it can be the basis of something less cumbersome. Note that I use a "fake" INNER JOIN just to get some variable initialized for the first time--it serves no other role.
SELECT ID,
supplier,
qty,
cumulative_qty
FROM
(
SELECT
ID,
supplier,
qty,
-- next line keeps a running total quantity by supplier id
#cumulative_quantity := if (#sup <> supplier, qty, #cumulative_quantity + qty) as cumulative_qty,
-- next is 0 for running total < 5 by supplier, 1 the first time >= 5, and ++ after
#reached_five := if (#cumulative_quantity < 5, 0, if (#sup <> supplier, 1, #reached_five + 1)) as reached_five,
-- next takes note of changes in supplier being processed
#sup := if(#sup <> supplier, supplier, #sup) as sup
FROM
(
--this subquery is key for getting things in supplier order, by descending id
SELECT *
FROM `sample_table`
ORDER BY supplier, ID DESC
) reverse_order_by_id
INNER JOIN
(
-- initialize the variables used to their first ever values
SELECT #cumulative_quantity := 0, #sup := 0, #reached_five := 0
) only_here_to_initialize_variables
) t_alias
where reached_five <= 1 -- only get things up through the time we first get to 5 or above.
How about this? Using two variables.
SQLFIDDLE DEMO
Query:
set #tot:=0;
set #sup:=0;
select x.id, x.supplier, x.ctot
from (
select id, supplier, qty,
#tot:= (case when #sup = supplier then
#tot + qty else qty end) as ctot,
#sup:=supplier
from demo
order by supplier asc, id desc) x
where x.ctot >=5
;
| ID | SUPPLIER | CTOT |
------------------------
| 2 | 1 | 5 |
| 1 | 1 | 7 |
| 3 | 2 | 5 |
Standard SQL has no concept of 'what row number am I up to', so this can only be implemented using something called a cursor. Writing code with cursors is something like writing code with for loops in other languages.
An example of how to use cursors is here:
http://dev.mysql.com/doc/refman/5.0/en/cursors.html
Here is a rough demo about cursor, may be it's helpful.
CREATE TABLE #t
(
ID INT IDENTITY,
Supplier INT,
QTY INT
);
TRUNCATE TABLE #t;
INSERT INTO #t (Supplier, QTY)
VALUES (1, 2),
(1, 2),
(2, 5),
(3, 2),
(1, 3);
DECLARE #sum AS INT;
DECLARE #qty AS INT;
DECLARE #totalRows AS INT;
DECLARE curSelectQTY CURSOR
FOR SELECT QTY
FROM #t
ORDER BY QTY DESC;
OPEN curSelectQTY;
SET #sum = 0;
SET #totalRows = 0;
FETCH NEXT FROM curSelectQTY INTO #qty;
WHILE ##FETCH_STATUS = 0
BEGIN
SET #sum = #sum + #qty;
SET #totalRows = #totalRows + 1;
IF #sum >= 5
BREAK;
END
SELECT TOP (#totalRows) *
FROM #t
ORDER BY QTY DESC;
CLOSE curSelectQTY;
DEALLOCATE curSelectQTY;
SELECT x.*
FROM supplier_stock x
JOIN supplier_stock y
ON y.supplier = x.supplier
AND y.id >= x.id
GROUP
BY supplier
, id
HAVING SUM(y.qty) <=5;