Sub-query with count(*) - mysql

How to get the data that is failed that associate with left(number,7) from sub query count(*) data?
For example I did this:
SELECT * FROM table1 WHERE outcome = 'Fail' AND left(number,7) =
(SELECT count(*) as total, left(number,7) as prefix
FROM table1 where outcome like '%Passed%'
group by prefix order by total desc limit 250)
This wont work because there are two fields in the sub-query.. so how to get around that?

You can use JOIN instead of subquery:
SELECT t1.*, t2.total, ...
FROM table1 AS t1
INNER JOIN
(
SELECT count(*) as total, left(number,7) as prefix
FROM table1
where outcome like '%Passed%' AND outcome = 'Fail'
group by prefix
order by total desc limit 250
) AS t2 ON t2.prefix = left(t1.number,7)

Try this query
SELECT *
FROM
table1 a
INNER JOIN
(SELECT
count(*) as total,
left(number,7) as prefix
FROM
table1
where
outcome like '%Passed%'
group by
prefix
order by
total desc limit 250)b
ON
a.outcome = 'Fail' AND
left(number,7) = b.prefix

Related

UNION with cross table where clause

(SELECT *, 0 AS user FROM table1)
UNION
(SELECT * FROM table2 WHERE unix >= {$threemonths})
ORDER BY unix DESC;
I need to add:
WHERE table2.identifier = table1.identifier or something
I want to get all from table1 and only rows from table2 where identifier is found in the results from table1's identifier column.
Please see if this works for you
(SELECT *, 0 AS user FROM table1)
UNION
(SELECT * FROM table2 WHERE unix >= {$threemonths} and exists (select 'Y' from table1 a where a.identifier = table2.identifier))
ORDER BY unix DESC;
Could be
SELECT *, 0 AS user FROM table1
UNION
SELECT * FROM table2 WHERE unix >= {$threemonths}
INNER JOIN table1 on table2.identifier = table1.identifier
ORDER BY unix DESC;

Why do I receive an error at this join tables?

I wrote this:
SELECT DISTINCT CATEGORY FROM T AS T1
CROSS JOIN (SELECT *
FROM T
WHERE T.CATEGORY = T1.CATEGORY
ORDER BY CATEGORY DESC
LIMIT 10)
and I receive this
"Unknown column 'T1.CATEGORY' in 'where clause'".
Why?
Update:
My purpose of this is to get 10 posts of any category.
Because T1 is not visible from within the subquery.
Your JOIN also serves no purpose and/or you probably forgot the JOIN condition.
In JOIN condition should use ON keyword
SELECT DISTINCT CATEGORY FROM T AS T1
CROSS JOIN SELECT * FROM T ON T.CATEGORY = T1.CATEGORY
ORDER BY CATEGORY DESC LIMIT 10;
If you need to get 10 posts of each category you can use a query like this:
SELECT CATEGORY, Post
FROM (
SELECT a.CATEGORY, a.Post, count(*) as rn
FROM #T a
JOIN #T b ON a.CATEGORY = b.CATEGORY AND a.Post >= b.Post
GROUP BY a.CATEGORY, a.Post) dt
WHERE rn < 11;

Update Inner Join Freeze

For some reason, this UPDATE query hang forever. If I replace to SELECT - it get the result instantly.
UPDATE table1 AS t1
INNER JOIN
(
SELECT count(*) as total, left(number,7) as prefix, outcome FROM table1
where outcome like '%Passed%'
group by prefix
order by total desc limit 200
) AS t2
ON t2.prefix = left(t1.number,7) AND t1.outcome = 'Fail'
SET t1.outcome = '', t1.status = 'NEW'
What is wrong there?
Try to move the ORDER BY and LIMIt to the end of the UPDATE. Something like:
UPDATE table1 AS t1
INNER JOIN
(
SELECT count(*) as total, left(number,7) as prefix, outcome FROM table1
where outcome like '%Passed%'
group by prefix
) AS t2 ON t2.prefix = left(t1.number, 7) AND t1.outcome = 'Fail'
SET t1.outcome = '', t1.status = 'NEW'
order by total desc
limit 200;
See the syntax of the UPDATE.
I would try something like this:
UPDATE table1
SET
table1.outcome = '',
table1.status = 'NEW'
WHERE
outcome = 'Fail'
AND
left(number,7) IN (SELECT * FROM (
SELECT left(number,7) as prefix
FROM table1
WHERE outcome like '%Passed%'
GROUP BY prefix
ORDER BY COUNT(*) desc limit 200
) s
)
Please see fiddle here.
Can you update the column on which you're joining? That is, t1.outcome.
Move the filter expression t1.outcome = 'Fail' out of the JOIN and in to a WHERE clause.
UPDATE table1 AS t1
INNER JOIN
(
SELECT count(*) as total, left(number,7) as prefix, outcome FROM table1
where outcome like '%Passed%'
group by prefix
order by total desc limit 200
) AS t2
ON t2.prefix = left(t1.number,7)
SET t1.outcome = '', t1.status = 'NEW'
WHERE t1.outcome = 'Fail'

Return rows around row with a certain value with joins

I have fairly complicated join query from which I want to select a few rows around a result with a certain id.
The query currently looks something like this:
WITH results AS
(
SELECT t1.id, t1.position, t1.points, t2.name
ROW_NUMBER() OVER(ORDER BY t1.position ASC, t1.points DESC) AS rn
FROM Table1 t1
JOIN Table2 t2 ON t1.id = t2.Table1id
/* Several more joins here, some of which limit the result set */
)
SELECT * FROM results
WHERE rn < ( SELECT rn+3 FROM results WHERE id = #someid )
AND rn > ( SELECT rn-3 FROM results WHERE id = #someid )
Is there a better way to solve this? Most of all I'm worried about performance with these multiple calls to a possibly huge CTE.
The query is run on a SQL 2008 server.
Maybe pull the joins out of the CTE.
That way the query optimizer has a chance filter out rows before processing the joins.
WITH results AS
(
SELECT t1.id, t1.position, t1.points
, ROW_NUMBER() OVER(ORDER BY t1.position ASC, t1.points DESC) AS rn
FROM Table1 t1
)
SELECT results.id, results.position, results.points, t2.name
FROM results
JOIN Table2 t2 ON t2.id = results.Table1id
/* Several more joins here */
WHERE rn < ( SELECT rn+3 FROM results WHERE id = #someid )
AND rn > ( SELECT rn-3 FROM results WHERE id = #someid )
You could use another cte to help form the filter:
WITH results AS (
SELECT
t1.id
, t1.position
, t1.points
, t2.name
, ROW_NUMBER() OVER (ORDER BY t1.POSITION ASC, t1.points DESC) AS rn
FROM Table1 t1
JOIN Table2 t2
ON t1.id = t2.Table1id
/* Several more joins here, some of which limit the result set */
),
filter AS (
SELECT
rn
FROM results
WHERE id = #someid
)
SELECT
*
FROM results
WHERE rn < ( SELECT rn + 3 FROM filter )
AND rn > ( SELECT rn - 3 FROM filter )

SQL select the last 3 dates from a table

I have a table with lots of fields in mysql
I need a query to return (in the same raw!) the top last 3 dates (dates can have large gaps between them)
ie:
2012/01/20
2012/01/18
2012/01/12
2012/01/10
2012/01/04
etc...
Any help will be appreciated
I must get them in the same row!
This is the query I am trying to use with no success:
SELECT a.id, a.thedate, b.id AS id1, b.thedate AS thedate1, c.id AS id2, c.thedate as thedate2
FROM mytable AS a INNER JOIN mytable AS b ON a.id = b.id INNER JOIN mytable AS c ON b.id=c.id
WHERE c.thedate = SELECT MAX(thedate)
EDIT :
SELECT group_concat(date) FROM (SELECT date FROM my_table ORDER BY date DESC LIMIT 3) AS temp
Corrected-
SELECT group_concat(date) FROM ( select date from table_name order by date desc limit 3) as a
SELECT GROUP_CONCAT(a.date )
FROM (
SELECT date
FROM my_table
ORDER BY date DESC
LIMIT 3
) AS a