I am trying to calculate the checkout conversion by using the following query but I keep getting error:
SELECT
(SELECT seller.name, count(checkout.id) AS 'Completed_checkout'
FROM checkout
JOIN seller
ON seller.id = checkout.seller_id
WHERE checkout.completed = 1
GROUP BY seller.name)
/
(SELECT seller.name, count(checkout.id) AS 'Total_Checkouts'
FROM checkout
JOIN seller
ON seller.id = checkout.seller_id
GROUP BY seller.name) * 100
AS 'Checkout_Converstion';
The end goal after being able to calculate it is:
filter by seller with more than 15 checkouts total
order it by DESC
limit it by then 5 first records
Any ideas on how to make this work?
How about simplifying this?
SELECT s.name, AVG(co.completed) as completed_ratio
FROM checkout co JOIN
seller s
ON s.id = co.seller_id
GROUP BY s.name;
If you want the counts:
SELECT s.name, AVG(co.completed = 1) as completed_ratio,
SUM(c.completed = 1) as num_completed,
COUNT(*) as total
FROM checkout co JOIN
seller s
ON s.id = co.seller_id
GROUP BY s.name;
These make use of the fact that MySQL treats boolean expressions as numbers in a numeric context -- with "1" for true and "0" for false.
You can do it with 1 query:
SELECT s.name,
100 * AVG(c.completed) AS Checkout_Conversion
FROM checkout c JOIN seller s
ON s.id = c.seller_id
GROUP BY s.id, s.name
HAVING SUM(c.completed) > 15
ORDER BY Checkout_Conversion DESC
LIMIT 5
Related
I want to select the columns with the max number of canceled trip. I know how to count the number of trips using the SQL statement, however, when I try to use the max function it gives the invalid group function error.
my SQL statement is as below:enter image description here
select t.ServiceNumber, t.RouteNumber, remark,
max(count(if(Cancelled =1 ,1,null))) as"Total Cancelled Trip"
from trip t inner join
route r
on r.ServiceNumber = t.ServiceNumber and
r.RouteNumber = t.RouteNumber
group by t.ServiceNumber, t.RouteNumber,remark;
If you want just one row with the maximum, you can do:
select t.ServiceNumber, t.RouteNumber, remark,
count(*) as "Total Cancelled Trip"
from trip t inner join
route r
on r.ServiceNumber = t.ServiceNumber and
r.RouteNumber = t.RouteNumber
where Cancelled = 1
group by t.ServiceNumber, t.RouteNumber, remark
order by count(*) desc
limit 1;
Getting all such rows in the event of ties is tricky in MySQL. Perhaps the easiest way uses variables:
select tr.*
from (select t.ServiceNumber, t.RouteNumber, remark,
count(*) as "Total Cancelled Trip",
(#maxtct = greatest(#maxtct, count(*))
from trip t inner join
route r
on r.ServiceNumber = t.ServiceNumber and
r.RouteNumber = t.RouteNumber cross join
(select #maxtct := 0) params
where Cancelled = 1
group by t.ServiceNumber, t.RouteNumber, remark
) tr
where `Total Cancelled Trip` = #maxtct;
A client can have more than one equipment (SerialNo). Each equipment has a cost and every month there is data recorded for each equipment. I'm trying to select only the first and last result for each equipment based on the queried period.
"
SELECT i.SerialNo
, p.Name
, c.Cost
, ci.DataDate
, ci.Data
,
FROM install i
JOIN product p USING (ProductId)
JOIN counter c USING (InstallId)
JOIN counter_item ci USING (CounterId)
WHERE i.ClientId LIKE $clientId
AND MONTH(ci.DataDate) BETWEEN $mStart AND $mEnd
";
This select works but it retrieves all records between the starting date and finishing date.
I tried, to get the top results and figured I would use A UNION ALL to combine with the bottom results (ci.DataDate ASC), but it's not working. I only get the first record encounter.
GROUP BY i.SerialNo
ORDER BY ci.DataDate DESC
It's like ORDER BY has no effect at all.
In counter_item you find the first and last DataDate per CounterId for the time range. So find these first by aggregation and use this information in order to join the desired records:
SELECT i.SerialNo,
p.Name,
c.Cost,
ci.DataDate,
ci.Data
FROM install i
JOIN product p ON p.ProductId = i.ProductId
JOIN counter c ON c.InstallId = i.InstallId
JOIN
(
SELECT CounterId, MIN(DataDate) AS MinDate, MAX(DataDate) AS MaxDate
FROM counter_item
WHERE MONTH(DataDate) BETWEEN $mStart AND $mEnd
GROUP BY CounterId
) minmax ON minmax.CounterId = c.CounterId
JOIN counter_item ci ON ci.CounterId = minmax.CounterId
AND ci.DataDate IN (minmax.MinDate, minmax.MaxDate)
WHERE i.ClientId LIKE $clientId
ORDER BY i.SerialNo, ci.DataDate
You could do it in next way, here is just general idea of how that could be done:
select * from table
where
([row] = (select max([row]) from table ) or
[Date] = (select min([row]) from table ))
You may also be able to use a cross apply. Something like this, untested rough sample:
SELECT i.SerialNo,
p.Name,
c.Cost,
MIN(ci.DataDate) as MinDate,
b.MaxDate,
ci.Data,
FROM install i
CROSS APPLY (SELECT
MAX(ci.DataDate) as MaxDate
FROM install
JOIN counter_item ci USING (CounterId)
WHERE i.ClientId LIKE $clientId
AND MONTH(ci.DataDate) BETWEEN $mStart AND $mEnd) b
WHERE i.ClientId LIKE $clientId
AND MONTH(ci.DataDate) BETWEEN $mStart AND $mEnd
GROUP BY i.SerialNo
ORDER BY ci.DataDate DESC
I have this query that I use in order to get records from several tables, using JOIN.
SELECT c.id AS contestant_id,
c.created_date,
c.name AS contestant_name,
counter.total AS score,
c.email
FROM submission AS s,
(SELECT ans.id AS ans_id, sub.contestant_id, count(sub.id) AS total
FROM submission AS sub
JOIN (SELECT id, is_true FROM answer) AS ans
WHERE sub.answer_id = ans.id
AND ans.is_true = 1
GROUP BY sub.contestant_id) AS counter
JOIN (SELECT id, name, email, type, created_date
FROM contestant
WHERE contest_type = 1
AND submission_status = 1) AS c
WHERE counter.contestant_id = c.id
GROUP BY c.id
ORDER BY c.created_date DESC
The problem is that each record in table contestant will have 30 record in the submission table. So, when I retrieve 1000 contestant or more, the server hangs.
Please try the following restructured query:
SELECT
c.id AS contestant_id,
c.created_date,
c.name AS contestant_name,
counter.total AS score,
c.email
FROM
(
SELECT
sub.contestant_id, count(sub.id) AS total
FROM
submission AS sub
JOIN answer AS ans
ON sub.answer_id = ans.id AND ans.is_true = 1
GROUP BY
sub.contestant_id
)
AS counter
JOIN contestant c
ON c.contest_type = 1 AND c.submission_status = 1 AND c.id = counter.contestant_id
WHERE
counter.contestant_id = c.id
GROUP BY
c.id
ORDER BY
c.created_date DESC
It is possible to change the query result row limit, or remove the limit entirely.
Go to "Edit -> Preferences... -> SQL Editor (tab)"
Locate the "Query Results" section and untick the "Limit Rows" checkbox
Click "OK"
Re-run your query
Exporting query results in MySQL Workbench beyond 1000 records
I'm not amazing at SQL and can't figure out how to do this. Here are the two queries I have at the moment.
SELECT TicketID_PK, SubProjectID_FK, ProjectID_FK, CustomerID_FK, TicketDate, TicketNumber,
SignOff, WorkOrder, ClientPO, TicketType, Description, Processed
FROM Tickets
INNER JOIN CustomersSubProjects ON Tickets.SubProjectID_FK = CustomersSubProjects.SubProjectID_PK
INNER JOIN CustomersProjects ON CustomersSubProjects.ProjectID_FK = CustomersProjects.ProjectID_PK
WHERE TicketID_PK = 1
SELECT ROUND(WCB+Vacation+Stat+UIC+CPP+Overhead,2) AS Total
FROM EmployeeFormula
WHERE EffectiveDate <= $TicketDate
ORDER BY EffectiveDate DESC LIMIT 1
I'm saving TicketDate as $TicketDate and using it in the second query, but I'm sure there is a way to combine the two queries to avoid this. Any help would be appreciated.
Edit: I need to select the EmployeeFormula Total (as shown in second query) by comparing the TicketDate column (in the Tickets table) to the EffectiveDate column. So the results should look like this:
TicketID_PK SubProjectID_FK ProjectID_FK CustomerID_FK TicketDate TicketNumber Total
1 1 1 1 2014-01-05 1-0501-00 30.78
Use like a subquery.
SELECT TicketID_PK, SubProjectID_FK, ProjectID_FK, CustomerID_FK, TicketDate, TicketNumber,
SignOff, WorkOrder, ClientPO, TicketType, Description, Processed, (SELECT ROUND(WCB+Vacation+Stat+UIC+CPP+Overhead,2) FROM EmployeeFormula WHERE EffectiveDate <= TicketDate ORDER BY EffectiveDate DESC LIMIT 1) AS Total
FROM Tickets
INNER JOIN CustomersSubProjects ON Tickets.SubProjectID_FK = CustomersSubProjects.SubProjectID_PK
INNER JOIN CustomersProjects ON CustomersSubProjects.ProjectID_FK = CustomersProjects.ProjectID_PK
WHERE TicketID_PK = 1
So I am trying to alter my sql code (see below for screenshot of current results + sql) to group the data by the month AND sum up all the paymentSplitAmounts. Each row should be a unique productId
So the end result would be something like
productID total month
1 500 11-2011
2 650 11-2011
3 250 11-2011
1 100 10-2011
2 150 10-2011
3 750 10-2011
I can't seem to get the syntax right. Where am I going wrong?
http://imgur.com/UC5Si
select
cpd.paymentId, cpd.paymentId, cpd.productId, cpd.paymentSplitAmount, cp.campaignId, cp.paymentDate
from campaign_payment_detail cpd
inner join
campaign_payment cp on cp.paymentId = cpd.paymentId
inner join product on cpd.productId = product.productId
where
1=1
and cp.campaignId = 2413
Looks like you want to group then sort your results:
SELECT cpd.productId, SUM(cpd.paymentSplitAmount), DATE_FORMAT(cp.paymentDate, '%b-%Y')
FROM campaign_payment_detail cpd
JOIN campaign_payment cp ON cp.paymentId = cpd.paymentId
JOIN product ON cpd.productId = product.productId
WHERE cp.campaignId = 2413
GROUP BY cpd.productId, DATE_FORMAT(cp.paymentDate, '%b-%Y')
ORDER BY cp.paymentDate DESC, cpd.productId ASC
edit: Using DATE_FORMAT to format the date like you want.
First, based on the query you provided and without other information, the table product is useless..
I will do that:
select
cpd.paymentId,
SUM(cpd.paymentSplitAmount) as total,
cp.campaignId,
cp.paymentDate
from campaign_payment_detail cpd
inner join
campaign_payment cp on cp.paymentId = cpd.paymentId
where
cp.campaignId = 2413
GROUP BY cpd.productId, cp.paymentDate
ORDER BY cpd.paymentId ASC, cp.paymentDate DESC
You already mentioned 'grouping'. For that you need to add group by to your query, to group the data by productid and month, then you can add sum to sum the paymentSplitAmount.
The grouping syntax isn't wrong, it is missing completely. :)
select
cpd.productId, sum(cpd.paymentSplitAmount) as total, date_format(cp.paymentDate, '%m-%Y')
from campaign_payment_detail cpd
inner join campaign_payment cp on cp.paymentId = cpd.paymentId
inner join product on cpd.productId = product.productId
where
cp.campaignId = 2413
group by cp.productId, date_format(cp.paymentDate, '%m-%Y')
order by date_format(cp.paymentDate, '%m-%Y') desc, cp.productId
This assumes cp.paymentDate already contains the months. If not, you will have to round each date to the first of the month and group by that.
Now groups by month.