How to calculate newTrades? - mysql

i.e. when new trades are in the current date trade list but not in the previous date trade list.
I have tried
SELECT COUNT(*) AS "Number of New Trades"
FROM TRADE_REPORT
WHERE business_date='2018-05-08' and excluded='false'
MINUS
SELECT COUNT(*) AS "Number of New Trades"
FROM TRADE_REPORT
WHERE business_date='2018-05-07'
and excluded='false'
But it did not worked

No. MINUS is a set operator, not an arithmetic operator, and it is not even available in MySQL. I think you want:
select count(*)
from trade_report tr
where tr.business_date = '2018-05-08' and tr.excluded = 'false' and
not exists (select 1
from trade_report tr2
where tr2.? = tr.? and
tr2.business_date = '2018-05-07' and
tr2.excluded = 'false'
);
The ? is for the id of what you want compare from one day to the next.

Consider a NOT IN clause capturing non-matches of IDs between the two days.
SELECT COUNT(*) AS "Number of New Trades"
FROM TRADE_REPORT t1
WHERE t1.business_date='2018-05-08' AND t1.excluded='false'
AND t1.ID NOT IN
(SELECT sub.ID
FROM TRADE_REPORT sub
WHERE sub.business_date='2018-05-07' AND sub.excluded='false')

Related

I want duplicates to be included with my in () statement

I want to include duplicates into my query. I havent succeeded in changing my "in" statements to "joins".
My expected result is a row count of 115.
My result is a row count of 108.
If i do a "Group by" in my first subquery, i get a row count of 108.
select match_id item_0, item_1, item_2, item_3, item_4, item_5, purchase_log
from player_matches where match_id IN
(select x.match_id from (select matches.match_id, picks_bans.team from matches, picks_bans where picks_bans.hero_id = 1 and picks_bans.match_id = matches.match_id and is_pick = true and start_time > 1483228800 ORDER BY start_time DESC) as x
inner join
(select matches.match_id, picks_bans.team from matches, picks_bans where picks_bans.hero_id
/*this is the statement that needs to be tweaked/changed */
IN (2,12,47,4,99) and picks_bans.match_id = matches.match_id and is_pick = true and start_time > 1483228800 ORDER BY start_time DESC) as y on y.match_id=x.match_id and x.team!=y.team)
and hero_id = 1
You can use the opendota inbrowser data-explorer to get a better understanding of my problem.
My subquery (returns 115)
My final Query (returns 108)
How do i get my final query to return 115 row counts?
My query is also really slow, is this because im using "in ()"?
It is because the IN will just check if the value is present. Use INNER JOIN instead:
select a.match_id, a.item_0, a.item_1, a.item_2, a.item_3, a.item_4, a.item_5, a.purchase_log
from player_matches a
INNER JOIN
(
select x.match_id from (select matches.match_id, picks_bans.team from matches, picks_bans where picks_bans.hero_id = 1 and picks_bans.match_id = matches.match_id and is_pick = true and start_time > 1483228800 ORDER BY start_time DESC) as x inner join (select matches.match_id, picks_bans.team from matches, picks_bans where picks_bans.hero_id in (2,12,47,4,5) and picks_bans.match_id = matches.match_id and is_pick = true and start_time > 1483228800 ORDER BY start_time DESC) as y on y.match_id=x.match_id and x.team!=y.team
) b ON a.match_id = b.match_id
WHERE hero_id = 1
Here's a demo from your original link.

select all data on type , and change select if a row exists

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

Two count request with double where and from in one query

I'm trying to count the number of occurrences of two values "1" and "2" in the "ticket" column, but I get an error when I add another line from "where" and "from".
"ticket" is a column, "tickets" is a table.
SELECT
COUNT(ticket) as child FROM tickets WHERE ticket = 1,
COUNT(ticket) as adult FROM tickets WHERE ticket = 2
GROUP by ticket
SELECT
COUNT(if(ticket = 1,1,NULL)) as child,
COUNT(if(ticket = 2,1,NULL)) as adult FROM tickets where ticket in (1,2)
GROUP by ticket
or
SELECT
sum(if(ticket = 1,1,0)) as child,
sum(if(ticket = 2,1,0)) as adult FROM tickets where ticket in (1,2)
GROUP by ticket
try like this
Use conditional aggregation:
SELECT SUM(t.ticket = 1) as t1,
SUM(t.ticket = 2) as t2
FROM tickets t;
You're looking for conditional aggregation, like so:
SELECT COUNT(IF(ticket=1, 1, NULL) AS child
, COUNT(IF(ticket=2, 1, NULL)) AS adult
FROM tickets
;
COUNT only counts non-null values.
Your query is syntactically invalid, try this one:
Select count(*)
, ticket
from tickets
where ticket In (1,2)
Group by ticket
;
Try this out and let me know in case of any queries.
SELECT SUM(ticket = 1) as t1,
SUM(ticket = 2) as t2
FROM tickets
group by tickets;

How to query mysql to select and group by multiple values

I'm trying to select and group by all the contentid values of the table below where the match criteria can be several different values.
the contentid values actually represent cars, so I need to select [and group by] all the contentis where the values are 'GMC' and the values are 'sedan' and the value is 'automatic.
i.e. I'm trying to select all the GMC sedans with an automatic transmission.
a query like this fails [obviously]:
select * from modx_site_tmplvar_contentvalues WHERE
`value` = 'gmc' and
`value` = 'tacoma'
group by contentid
I have no idea how to create a query like that. Any suggestions?
You need to "pivot" these data on "tmplvarid", but unfortunately for you MySQL doesn't have a PIVOT statement like other RDBMS. However, you can pivot it yourself by joining in the table multiple times for each variable you care about:
SELECT
contents.contentid,
transmission.value as transmission,
type.value as type,
make.value as make
FROM
(SELECT DISTINCT contentid FROM modx_site_tmplvar_contentvalues) AS contents
LEFT JOIN
modx_site_tmplvar_contentvalues AS transmission
ON contents.contentid = transmission.contentid
AND transmission.tmplvarid = 33 -- id for transmission
LEFT JOIN
modx_site_tmplvar_contentvalues AS make
ON contents.contentid = make.contentid
AND make.tmplvarid = 13 -- id for make
LEFT JOIN
modx_site_tmplvar_contentvalues AS type
ON contents.contentid = type.contentid
AND type.tmplvarid = 17 -- id for type
WHERE
type.value = 'sedan'
AND make.value = 'GMC'
AND transmission.value = 'automatic'
You can expand this with additional joins for other criteria such as year (id 15) or mileage (id 16).
If you need to use the value only, you could try:
SELECT DISTINCT
contents.contentid,
transmission.value as transmission,
type.value as type,
make.value as make
FROM
(SELECT DISTINCT contentid FROM modx_site_tmplvar_contentvalues) AS contents
INNER JOIN
modx_site_tmplvar_contentvalues AS transmission
ON contents.contentid = transmission.contentid
AND transmission.value = 'automatic'
INNER JOIN
modx_site_tmplvar_contentvalues AS make
ON contents.contentid = make.contentid
AND make.value = 'GMC'
INNER JOIN
modx_site_tmplvar_contentvalues AS type
ON contents.contentid = type.contentid
AND type.value = 'sedan'
In any case, make sure you have an index on the value column; these queries are going to get slow.
please try this:
SELECT *
FROM modx_site_tmplvar_contentvalues t1 INNER JOIN modx_site_tmplvar_contentvalues t2 ON t1.contentid = t2.content_id
WHERE
t1.`value` = 'gmc'
AND t2.`value` = 'tacoma';
You can do this with a group by. This is the most flexible in terms of expressing the conditions. In MySQL, multiple joins will often perform better:
select contentid
from modx_site_tmplvar_contentvalues
group by contentid
having sum(`value` = 'gmc') > 0 and
sum(`value` = 'tacoma') > 0;
This is always false:
`value` = 'gmc' and
`value` = 'tacoma'
Instead, use OR:
`value` = 'gmc' OR
`value` = 'tacoma'
In a condition "and" means "this and this is true at the same time". If you want all foos and all bars, then your condition is "foo OR bar".
EDIT:
To select groups containing your values, you can write subqueries:
SELECT DISTINCT name FROM table WHERE name IN (SELECT name FROM table WHERE value='value1') AND name IN (SELECT name FROM table WHERE value='value2')

Count only unique terms based on inner SELECT JOIN

I'm trying to count only unique terms as a TOTAL count.
This is the original query and it works fine
->select('DISTINCT search_tags.term AS t_name, nbr', FALSE)
->from('search_tags LEFT JOIN (SELECT term AS tk, COUNT(search_tags.term) AS nbr FROM search_tags GROUP BY search_tags.term) AS TR ON search_tags.term = TR.tk ')
->where('search_tags.dt_added >=', '2011-08-01 09:48:54')
->where('search_tags.dt_added <=', '2011-09-02 09:48:54');
// returns: [twitter,12],[facebook,6].....
The thing is that this code runs a datatable (datatable.net) so the datatable removes the select line and change it to:
SELECT COUNT(*) AS numrows
FROM (search_tags LEFT JOIN (SELECT term AS tk, COUNT(search_tags.term) AS nbr FROM search_tags GROUP BY search_tags.term) AS TR ON search_tags.term = TR.tk)
WHERE `search_tags`.`dt_added` >= '2011-08-01 09:48:54'
AND `search_tags`.`dt_added` <= '2011-09-02 09:48:54'
// returns the same [twitter,12],[facebook,6]..... BUT the pagination is broken.
So the datatable can count the rows and use it as a pagination param.
But when it removes the select, it get all the rows as the DISTINCT is not there anymore.
I'm sleep deprived so I'm like stuck on try and error forever. Please help lol :P
Sorted out
->select('DISTINCT st5.term AS t_name, n_ocurrences', FALSE)
->from("search_tags AS st4
RIGHT OUTER JOIN (SELECT DISTINCT st.term, n_ocurrences
FROM search_tags AS st
JOIN
(SELECT term AS n_term, COUNT(term) AS n_ocurrences
FROM search_tags AS st2
GROUP BY st2.term)
AS st3 ON st3.n_term = st.term
WHERE st.dt_added >= '$min'
AND st.dt_added <= '$max') AS st5 ON st5.term = 1");
Had to add some inception selects to retrieve the right amount.
Now I need to count the UNIQUE n_ocurrences under the $min, $max as the n_ocurrences is returning only the overall count.