SQL numbering merge if string is the same - mysql

I want to create a stats page for my website. However I have the problem that if I run my query it will not be merged if the sting is the same. Any idea how to fix this?
My query:
SELECT * FROM (
SELECT dj_1, count(*) AS uren
FROM dj_rooster
WHERE week = '28' GROUP BY id_1
ORDER BY count(*) DESC
) x
UNION ALL
SELECT * FROM (
SELECT dj_1, count(*) AS uren
FROM djpaneel_shows_uren
WHERE week = '28' AND active = '1'
GROUP BY dj_1
ORDER BY count(*) DESC
) x
My results:
Jack - 7
Jeremy - 5
Jack - 1
Thanks in advance for your help

There is no need to aggregate twice or more.
Use UNION ALL to get all the rows from the 2 tables and then aggregate:
SELECT t.dj_1, COUNT(*) AS uren
FROM (
SELECT dj_1 FROM dj_rooster
WHERE week = '28'
UNION ALL
SELECT dj_1 FROM djpaneel_shows_uren
WHERE week = '28' AND active = '1'
) t
GROUP BY t.dj_1
ORDER BY uren DESC

Related

Top 10 players with the highest batting average

Batting average = total number of runs scored / number of times out.
Here we need to make sure to include run outs (on non-striker end)
Output like :
Batsman_name Average
KL Rahul 44
Error:
Error in SQL statement: AnalysisException: cannot resolve 'batsman_runs' given input columns: [_auto_generated_subquery_name.Batsman]; line 1 pos 21;
'Sort ['Average DESC NULLS LAST], true
select Batsman_, sum(batsman_runs)/count(player_dismissed) as Average
from
(
(select batsman as Batsman_ from IPL_BALL_BY_BALL)
union all
(select non_striker as Batsman_ from IPL_BALL_BY_BALL)
)
group by Batsman_
order by Average desc;
because from your subquery ( result of union) you only returning "Batsman_" column. you have to retunr all the column you need :
select Batsman_, sum(batsman_runs)/count(player_dismissed) as Average
from
(
(select batsman as Batsman_,batsman_runs,player_dismissed from IPL_BALL_BY_BALL)
union all
(select non_striker as Batsman_,batsman_runs,player_dismissed from IPL_BALL_BY_BALL)
)
group by Batsman_
order by Average desc;
select Batsman_, sum(batsman_runs)/count(player_dismissed) as Average from
((select batsman as Batsman_,batsman_runs,player_dismissed from IPL_BALL_BY_BALL) union all (select non_striker as Batsman_,batsman_runs,player_dismissed
from IPL_BALL_BY_BALL))
group by Batsman_ order by Average desc;
You forgot fields "batsman_run & player_dismissed" in your inner sql

How to select last and last but one records

I have a table with 3 columns id, type, value like in image below.
What I'm trying to do is to make a query to get the data in this format:
type previous current
month-1 666 999
month-2 200 15
month-3 0 12
I made this query but it gets just the last value
select *
from statistics
where id in (select max(id) from statistics group by type)
order
by type
EDIT: Live example http://sqlfiddle.com/#!9/af81da/1
Thanks!
I would write this as:
select s.*,
(select s2.value
from statistics s2
where s2.type = s.type
order by id desc
limit 1, 1
) value_prev
from statistics s
where id in (select max(id) from statistics s group by type) order by type;
This should be relatively efficient with an index on statistics(type, id).
select
type,
ifnull(max(case when seq = 2 then value end),0 ) previous,
max( case when seq = 1 then value end ) current
from
(
select *, (select count(*)
from statistics s
where s.type = statistics.type
and s.id >= statistics.id) seq
from statistics ) t
where seq <= 2
group by type

SQL where exists

I am trying to get the total amount spent on transactions with a specific product sold during the period below.
SELECT
i.Customer,
SUM(i.GrandTotal)
FROM
transaction i
WHERE EXISTS
(SELECT
1
FROM
transactionline il
INNER JOIN product p
ON p.ProductId = il.ProductId
WHERE i.InvoiceDate >= '2016-09-01 00:00:00'
AND i.InvoiceDate <= '2017-08-31 23:59:59'
AND p.TableProductType = 25)
GROUP BY i.Customer;
My problem is that this query has a result the total amount spent during that period and not only transactions with that product involved
I started of with something like this :
SELECT
i.Customer,
SUM(i.GrandTotal)
FROM
transaction i,transactionline il , product p
WHERE i.InvoiceDate >= '2016-09-01 00:00:00'
AND i.InvoiceDate <= '2017-08-31 23:59:59'
AND p.TableProductType = 25);
But this also took much longer and the final result was wrong (cause of the multiplication caused by the join between transaction and transaction line)
few ways, all solutions using the with following as its data source directly before query, but substitute with your table name
with dat
as
(
select 1 tranid,'N' Tableproducttype,9.00 GrandTotal union all
select 1,'N',11.12 union all
select 1,'N',14.23 union all
select 1,'25',8.88 union all
select 1,'N',7.77 union all
select 1,'Y',6.66 union all
select 2,'N',3.21 union all
select 2,'N',19.13 union all
select 2,'Y',1.23 union all
select 3,'Y',4.31 union all
select 4,'Y',15.43 union all
select 4,'Y',15.12 union all
select 5,'N',14.32)
1.) works using an IN
select tranid,sum(GrandTotal) GrandTotal
from dat
where tranid in (select tranid from dat where TableProductType = '25')
group by tranid
2.) using an exists
select tranid,sum(GrandTotal) GrandTotal
from dat
where exists (select 'x' from dat dat_inner
where dat_inner.TableProductType = '25'
and dat_inner.tranid = dat.tranid)
group by tranid
3.) using having, but could be slow
select tranid,sum(GrandTotal) GrandTotal
from dat
group by tranid
having sum(case when TableProductType = '25' then 1 else 0 end)>0 /* at least one product of type 25 */

Reorder results from another query

SELECT * FROM (
SELECT * FROM cars WHERE site = '5'
ORDER BY cost DESC LIMIT 0 , 10
)
ORDER BY time
How would I execute a sql query like this? So first it selects the 10 cars with the highest cost, THEN it reorders those 10 cars by what time they were added to the DB.
I tried to figure it out but I just cannot get a grip on the syntax :P
Just give an alias to the sub-query.
SELECT * FROM (
SELECT * FROM `cars` WHERE `site` = '5'
ORDER BY `cost` DESC LIMIT 0 , 10
)t
ORDER BY `time`;
This query will give you the desired results
SELECT * FROM ( SELECT * FROM cars WHERE site = 5
ORDER BY cost DESC LIMIT 0 , 10 ) as t ORDER BY time

ExpressionEngine query module and ordering SQL UNION

I'm receiving a MySQL Error on this code in ExpressionEngine 1.6.4 (very old version)
{exp:query limit="10" paginate="bottom"
sql="SELECT 'gallery' AS `content_type`, `cat_id` AS `entry_id`, `recent_entry_date` AS `entry_date`
FROM `exp_gallery_categories`
WHERE `gallery_id` = 9 AND total_files > 0
UNION
SELECT 'video' AS `content_type`, `entry_id`, `entry_date`
FROM `exp_weblog_titles`
WHERE `weblog_id` = 6 ORDER BY `entry_date` DESC"
}
<p>{content_type} - {entry_id} - {entry_date format="%d %F %Y"}</p>
{paginate}{pagination_links}{/paginate}
{/exp:query}
MySQL returns this:
MySQL ERROR: Error Number: 1054
Description: Unknown column 'entry_date' in 'order clause'
Query: SELECT COUNT(*) AS count FROM `exp_gallery_categories` WHERE `gallery_id` = 9 AND total_files > 0 UNION SELECT COUNT(*) AS count FROM `exp_weblog_titles` WHERE `weblog_id` = 6 ORDER BY `entry_date` DESC
It seems like EE is modifying my query before MySQL and making it fail (On a SQL client this works smoothly).
The answer is to patch mod.query.php to stop modifing the query
$query = $DB->query("SELECT COUNT(*) AS count FROM ({$sql}) AS query");
Here is the ultimate in-depth answer by Dom Stubbs: ExpressionEngine 1 Query Module and Ordering SQL UNION
I am assuming your select queries work. Try below:
sql="SELECT * FROM
(SELECT gallery AS content_type, cat_id AS entry_id,
recent_entry_date AS entry_date
FROM exp_gallery_categories
WHERE gallery_id = 9 AND total_files > 0
UNION
SELECT video AS content_type, entry_id, entry_date
FROM exp_weblog_titles
WHERE weblog_id= 6
) AS TEMP
ORDER BY entry_date DESC"
EDIT: Count query:
SELECT COUNT(*) AS count
FROM
( SELECT COUNT(*) AS count,
recent_entry_date AS entry_date
FROM exp_gallery_categories
WHERE gallery_id = 9 AND total_files > 0
UNION
SELECT COUNT(*) AS count,
entry_date
FROM exp_weblog_titles
WHERE weblog_id = 6
) AS TEMP
ORDER BY entry_date DESC