I am wondering if there is a way to make this work. I am deriving a table "WHERE lie_start='green'" (and a bunch of other conditions which i don't wanna repeat), need to get the number (and several other information) off it.
Additionally I need the number of entries with the additional condition lie_finish='holed'. Currently I'm gettin the error: Table mydb.x doesnt exist.
SELECT
COUNT(*) AS total,
(SELECT COUNT(*) FROM x WHERE lie_finish='holed') as holed
FROM (SELECT * FROM mydb.strokes WHERE lie_start='green') as x
You need to repeat the table name. The table alias is not recognized:
SELECT COUNT(*) AS total,
(SELECT COUNT(*) FROM mydb.strokes WHERE lie_finish='holed') as holed
FROM (SELECT * FROM mydb.strokes WHERE lie_start='green') as x;
However, this is much more simply written as:
select count(*) as total, sum(lie_finish = 'holed') as holed
from mydb.strokes s
where lie_start = 'green';
Related
I am not able to further select from a joined subquery.
I have data in three tables: "events", "records" and "work_list". Each table has one piece of the puzzle where work_list is the shortest and contains top-level data, and the events table tracks many tiny frequent events.
I need to calculate many statistical variables from the events based on some key variables defined in work_list like weighted moving average etc. I have those metrics ready and working, but I have problems filtering the data in events based on selected parameters stored in work_list.
Here is code that does not work. The SELECT * is not important, I will change it to be more meaningful later, it is for clarity. However, I have tried many selections in place of the * without success.
What is wrong with this query from subquery?
Query example 1:
SELECT * FROM
(SELECT events.id, events.type,events.timestamp, work_list.task
FROM
( events
INNER JOIN records ON events.record_id = records.id
INNER JOIN work_list ON records.work_list_id = work_list.id
)
WHERE work_list.customer_number = '1234' AS subquery
);
#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'as subquery ) LIMIT 0, 25' at line 8
The inner joined subquery works and it returns a normal table.
Query example 2:
SELECT events.id, events.type,events.timestamp, work_list.task
FROM (
events
INNER JOIN records ON events.record_id = records.id
INNER JOIN work_list ON records.work_list_id = work_list.id
)
WHERE work_list.customer_number = '1234';
I tried using parenthesis in different orders, and I changed selected variables in SELECT events.id, events.type,events.timestamp, work_list.task. I wonder if this is a poor way of doing this. I have the calculation part. So even if there might be better structures for this, I am interested in solutions that maintain this structure.
The goal of this phase is to filter the events table for further queries that are coded on top of it replacing the SELECT *.
These are the final calculations made earlier which I plan to use when I figure out the problem with Query example 1.
Query example 3:
SELECT *, ((SUM(rate * diff) OVER (ORDER BY startTime
ROWS BETWEEN 4 PRECEDING AND CURRENT ROW)) /
(SUM(diff) OVER(ORDER BY startTime
ROWS BETWEEN 4 PRECEDING AND CURRENT ROW))) as rate_WMA
FROM (
SELECT id, startTime, counts, diff, (counts / diff)*3600 as rate
FROM (
SELECT id, TIMESTAMPDIFF(SECOND, MIN(timestamp), MAX(timestamp))AS diff, SUM(change) as counts, MIN(timestamp) as startTime
FROM `the filered subquery here`
GROUP BY id
) AS subquery
WHERE diff > 0
) AS totaltotal;
You have extra parenthesis (no need for those) and the alias for the subquery should be placed after the subquery:
SELECT *
FROM (
SELECT events.id, events.type,events.timestamp, work_list.task
FROM events
INNER JOIN records ON events.record_id = records.id
INNER JOIN work_list ON records.work_list_id = work_list.id
WHERE work_list.customer_number = '1234'
) AS subquery;
I am trying to perform a SUM based on multiple distinct counts for specific columns on a SQL table. The issue so far is I can am unable to perform this sum while I thought the synthax would be okay. But it seems not since I constantly get an issue from this query.
select SUM(`s1`.`t1`) from (
select
COUNT(DISTINCT s1_global) from NPS_deploiement_synthese as s1 where hubspot_company_id = 2436352252
union
select
COUNT(DISTINCT s2_global) from NPS_deploiement_synthese as s1 where hubspot_company_id = 2436352252
) as t1;
You don't need a subquery at all:
select COUNT(DISTINCT s1_global) + COUNT(DISTINCT s2_global)
from NPS_deploiement_synthese s
where hubspot_company_id = 2436352252;
Your version could conceivably work, but the subquery needs column aliases.
You can add the 2 count():
select
COUNT(DISTINCT s1_global) + COUNT(DISTINCT s2_global)
from NPS_deploiement_synthese as s1
where hubspot_company_id = 2436352252
I have a populated table with a 'Number' as PK. I would like a query which searches for a specific number, and if it is not found then it would return "NULL" not a no value.
I have managed to do it for one return:
SELECT (SELECT Risk_Impact FROM [dbo].[RFC] WHERE Number = 'RFC-018345')
However I would like to select multiple columns like:
SELECT (SELECT Risk_Impact, Risk_Impact, BI_TestingOutcome FROM [dbo].[RFC] WHERE Number = 'RFC-018345')
However it is giving me an error:
"Msg 116, Level 16, State 1, Line 1
Only one expression can be specified in the select list when the subquery is not introduced with EXISTS."
Can you please assist?
Thank you in advance
Try
select p.* from (select 1 as t ) v
left join (select * from [dbo].[RFC] WHERE Number = 'RFC-018345') p
on 1=1
In sql server should be use isnull function like this
SELECT isnull((SELECT Risk_Impact FROM [dbo].[RFC] WHERE Number = 'RFC-018345'),0)
Refined #Sagar query:
And better indentation would probably be more helpful for people to learn from.
Ex:
SELECT
[dbo].[RFC].*
FROM
(SELECT 1 AS Col1) AS V
CROSS JOIN
[dbo].[RFC]
WHERE Number = 'RFC-018345'
Edit: I got caught up in removing the subquery. Working query:
SELECT
[dbo].[RFC].*
FROM
(SELECT 1 AS Col1) AS V
LEFT JOIN
[dbo].[RFC]
ON Number = 'RFC-018345'
(I would also advocate to not SELECT *, anywhere near production, but to always be explicit about the columns in the result set. Ex:
SELECT
[dbo].[RFC].[Risk_Impact],
[dbo].[RFC].[BI_TestingOutcome]
FROM
(SELECT 1 AS Col1) AS V
LEFT JOIN
[dbo].[RFC]
ON Number = 'RFC-018345'
)
There is a table called m_techno_idea(stores ideas), m_techno_idea_moderator_vote(moderator votes), and m_techno_idea_user_vote(for uservotes). User vote is only 1 while moderator vote is between 1 -5 and is stored in the column named votes. So I need to get the total no. of votes in a single query. I don't want a nested query.
My Attempts:
Attempt 1:
SELECT
COUNT(DISTINCT TIUV.PK_ID) + IFNULL((SUM(TIMV.VOTES)),0) AS VOTES
FROM
M_TECHNO_IDEA TI
LEFT OUTER JOIN
M_TECHNO_IDEA_MODERATOR_VOTE TIMV
ON
TIMV.FK_TECHNO_IDEA_ID=TI.PK_ID
LEFT OUTER JOIN
M_TECHNO_IDEA_USER_VOTE TIUV
ON
TIUV.FK_TECHNO_IDEA_ID=TI.PK_ID
WHERE
TI.PK_ID=2
Here distinct keyword helps me to have distinct rows for user votes but for moderator votes I can't use distinct, as the votes can be same in many rows.This gives me wrong results.
Attempt 2:
SELECT (select count(TIUV.PK_ID) FROM M_TECHNO_IDEA_USER_VOTE TIUV
WHERE TIUV.FK_TECHNO_IDEA_ID=2) +
(select sum(TIMV.VOTES) FROM M_TECHNO_IDEA_moderator_VOTE TIMV
WHERE TIMV.FK_TECHNO_IDEA_ID=2) AS VOTES
Attempt 2 gives me correct results but the query doesn't look good. I have tried group by also but it didn't help me too. Any Help will be appreciated.
Attempt 3:
SELECT
COUNT(DISTINCT TIUV.PK_ID) + IFNULL(MODVOTES.VOTES, 0) AS VOTES
FROM
(SELECT
TIMV.FK_TECHNO_IDEA_ID, SUM(TIMV.VOTES) VOTES
FROM
M_TECHNO_IDEA_MODERATOR_VOTE TIMV
GROUP BY TIMV.FK_TECHNO_IDEA_ID) MODVOTES
LEFT OUTER JOIN
M_TECHNO_IDEA_USER_VOTE TIUV ON TIUV.FK_TECHNO_IDEA_ID = MODVOTES.FK_TECHNO_IDEA_ID
WHERE
TIUV.FK_TECHNO_IDEA_ID = 2
This attempt also gives me the correct result. I had to place a nested sub query. If a better solution comes, it would be appreciated.
To achieve this, "I simply want to get the sum of two votes stored in two different tables", use a derived table. Here is the general idea.
select sum(votes) totalvotes
from (
select count(something) votes
from TheFirstTable
where whatever
union
select count(something) votes
from TheSecondTable
where whatever ) ThisIsCalledADerivedTable
You can put together the derived table to suit your requirements.
Your second attempt is good, except you can clean it up a lot by removing unnecessary aliases, using consistent letter-casing and a little formatting:
SELECT
(SELECT COUNT(*) FROM M_TECHNO_IDEA_USER_VOTE WHERE FK_TECHNO_IDEA_ID = 2) +
(SELECT SUM(VOTES) FROM M_TECHNO_IDEA_moderator_VOTE WHERE FK_TECHNO_IDEA_ID = 2)
AS VOTES
I have something like this:
SELECT id, fruit, pip
FROM plant
WHERE COUNT(*) = 2;
This weird query is self explanatory I guess. COUNT(*) here means the number of rows in plant table. My requirement is that I need to retrieve values from specified fields only if total number of rows in table = 2. This doesn't work but: invalid use of aggregate function COUNT.
I cannot do this:
SELECT COUNT(*) as cnt, id, fruit, pip
FROM plant
WHERE cnt = 2;
for one, it limits the number of rows outputted to 1, and two, it gives the same error: invalid use of aggregate function.
What I can do is instead:
SELECT id, fruit, pip
FROM plant
WHERE (
SELECT COUNT(*)
FROM plant
) = 2;
But then that subquery is the main query re-run. I'm presenting here a small example of the larger part of the problem, though I know an additional COUNT(*) subquery in the given example isn't that big an overhead.
Edit: I do not know why the question is downvoted. The COUNT(*) I'm trying to get is from a view (a temporary table) in the query which is a large query with 5 to 6 joins and additional where clauses. To re-run the query as a subquery to get the count is inefficient, and I can see the bottleneck as well.
Here is the actual query:
SELECT U.UserName, E.Title, AE.Mode, AE.AttemptNo,
IF(AE.Completed = 1, 'Completed', 'Incomplete'),
(
SELECT COUNT(DISTINCT(FK_QId))
FROM attempt_question AS AQ
WHERE FK_ExcAttemptId = #excAttemptId
) AS Inst_Count,
(
SELECT COUNT(DISTINCT(AQ.FK_QId))
FROM attempt_question AS AQ
JOIN `question` AS Q
ON Q.PK_Id = AQ.FK_QId
LEFT JOIN actions AS A
ON A.FK_QId = AQ.FK_QId
WHERE AQ.FK_ExcAttemptId = #excAttemptId
AND (
Q.Type = #descQtn
OR Q.Type = #actQtn
AND A.type = 'CTVI.NotImplemented'
AND A.IsDelete = #status
AND (
SELECT COUNT(*)
FROM actions
WHERE FK_QId = A.FK_QId
AND type != 'CTVI.NotImplemented'
AND IsDelete = #status
) = 0
)
) AS NotEvalInst_Count,
(
SELECT COUNT(DISTINCT(FK_QId))
FROM attempt_question AS AQ
WHERE FK_ExcAttemptId = #excAttemptId
AND Mark = #mark
) AS CorrectAns_Count,
E.AllottedTime, AE.TimeTaken
FROM attempt_exercise AS AE
JOIN ctvi_exercise_tblexercise AS E
ON AE.FK_EId = E.PK_EId
JOIN ctvi_user_table AS U
ON AE.FK_UId = U.PK_Id
JOIN ctvi_grade AS G
ON AE.FK_GId = G.PK_GId
WHERE AE.PK_Id = #excAttemptId
-- AND COUNT(AE.*) = #number --the portion in contention.
Kindly ignore the above query and guide me to right direction from the small example query I posted, thanks.
In MySQL, you can only do what you tried:
SELECT id, fruit, pip
FROM plant
WHERE (
SELECT COUNT(*)
FROM plant
) = 2;
or this variation:
SELECT id, fruit, pip
FROM plant
JOIN
(
SELECT COUNT(*) AS cnt
FROM plant
) AS c
ON c.cnt = 2;
Whether the 1st or the 2nd is more efficient, depends on the version of MySQL (and the optimizer). I would bet on the 2nd one, on most versions.
In other DBMSs, that have window functions, you can also do the first query that #Andomar suggests.
Here is a suggestion to avoid the bottleneck of calculating the derived table twice, once to get the rows and once more to get the count. If the derived table is expensive to be calculated, and its rows are thousands or millions, calculating them twice only to throw them away, is a problem, indeed. This may improve efficiency as it will limit the intermediately (twice) calculated rows to 3:
SELECT p.*
FROM
( SELECT id, fruit, pip
FROM plant
LIMIT 3
) AS p
JOIN
( SELECT COUNT(*) AS cnt
FROM
( SELECT 1
FROM plant
LIMIT 3
) AS tmp
) AS c
ON c.cnt = 2 ;
After re-reading your question, you're trying to return rows only if there are 2 rows in the entire table. In that case I think your own example query is already the best.
On another DBMS, you could use a Windowing function:
select *
from (
select *
, count(*) over () as cnt
from plant
) as SubQueryAlias
where cnt = 2
But the over clause is not supported on MySQL.
old wrong anser below
The where clause works before grouping. It works on single rows, not groups of rows, so you can't use aggregates like count or max in the where clause.
To set filters that work on groups of rows, use the having clause. It works after grouping and can be used to filter with aggregates:
SELECT id, fruit, pip
FROM plant
GROUP BY
id, fruit, pip
HAVING COUNT(*) = 2;
The other answers do not fulfill the original question which was to filter the results "without using a subquery".
You can actually do this by using a variable in 2 consecutive MySQL statements:
SET #count=0;
SELECT * FROM
(
SELECT id, fruit, pip, #count:=#count+1 AS count
FROM plant
WHERE
) tmp
WHERE #count = 2;