SELECT COUNT() in a left join table mysql - php

I am attempting to count the number of new leads and the number of closed leads in any given month. The query below returns the month array correctly, but then only counts 1 if there are any leads or closes in the months, instead of the actual number that happened in that month. Any ideas what I am doing wrong?
query:
$productSql = "SELECT months.monthnum as monthnum, COUNT(contacts.lead_date) as lead_date_month, COUNT(contacts.close_date) as close_date_month, contacts.rep as rep
FROM months
LEFT JOIN contacts
ON months.monthnum = MONTH(contacts.lead_date)
AND months.monthnum = MONTH(contacts.close_date)
AND contacts.compid='$compid'
AND YEAR(contacts.lead_date) = '$year'
AND YEAR(contacts.close_date) = '$year'
AND contacts.rep = '$rep'
GROUP BY months.monthnum
ORDER BY months.monthnum ASC";
$productResult = mysql_query($productSql, $link) or die(mysql_error());
$label[] = $productRow['monthnum'];
$lead[] = $productRow['lead_date_month'];
$close[] = $productRow['close_date_month'];
};
echo "[".json_encode($label).",".json_encode($lead).",".json_encode($close)."]";
result:
[["January","February","March","April","May","June","July","August","September","October","November","December"],
["0","0","0","0","0","0","0","0","1","1","0","0"],
["0","0","0","0","0","0","0","0","1","1","0","0"]]
**Please don't chastise me for using mysql. I am dumping it as soon as this project is finished.

The way you build your JOIN condition you will get results only from records with MONTH(contacts.lead_date) = MONTH(contacts.close_date).
To fix that and to get your actual Count I would suggest splitting the statement into two queries:
SELECT
a.monthnum,
a.lead_date_month, b.close_date_month,
b.close_date_month / a.lead_date_month
FROM
(
-- Count number of new leads
SELECT
months.monthnum as monthnum,
COUNT(*) as lead_date_month,
contacts.rep as rep
FROM
months
LEFT JOIN contacts
ON
months.monthnum = MONTH(contacts.lead_date)
AND contacts.compid='$compid'
AND YEAR(contacts.lead_date) = '$year'
AND contacts.rep = '$rep'
GROUP BY
months.monthnum
ORDER BY
months.monthnum ASC
) as a
JOIN
(
-- Count number of closed leads
SELECT
months.monthnum as monthnum,
COUNT(*) as close_date_month,
contacts.rep as rep
FROM
months
LEFT JOIN contacts
ON
months.monthnum = MONTH(contacts.close_date)
AND contacts.compid='$compid'
AND YEAR(contacts.close_date) = '$year'
AND contacts.rep = '$rep'
GROUP BY
months.monthnum
ORDER BY
months.monthnum ASC
) as b
ON a.monthnum = b.monthnum
And MySQL isn't that bad. But MariaDB is better, you are right :-)

Related

How to get the latest record by date and not the first from a table?

In my query i get the first record i olje table when i group by frl_nr. There are many records with the same frl_nr i the olje table. I want to get the latest record from the olje table by date column. Her is my search string:
$sql = "SELECT *
FROM frl_sok
INNER JOIN olje ON frl_sok.id_nr = olje.id_nr
WHERE frl_sok.kunde_nr = '$kunde'
AND frl_sok.jobb_nr = '$jobb_nr'
GROUP BY frl_sok.frl_nr DESC";
What is the solution?
Both of my tables are here
You should use row_number() rather than trying to group by.
Try this:
select * from (
SELECT *,
row_number() over (partion by frl_sok.frl_nr order by date desc) rn
FROM frl_sok
INNER JOIN olje ON frl_sok.id_nr = olje.id_nr
WHERE frl_sok.kunde_nr = '$kunde'
AND frl_sok.jobb_nr = '$jobb_nr'
) q where rn=1"
Here is the solution I came up with and it works.
$sql = "SELECT a.id_nr, a.frl_nr, a.maskin_id, a.tilstand_olje, b.date FROM frl_sok a INNER JOIN olje b ON a.id_nr = b.id_nr INNER JOIN (SELECT id_nr, MAX(date) Max_Date FROM olje GROUP BY id_nr) c ON b.id_nr = c.id_nr AND b.date = c.Max_date WHERE a.kunde_nr = '$kunde' AND a.jobb_nr = '$jobb_nr'";

Fetching the wrong amount in database using SELECT DISTINCT COUNT

I am tracking when sellers sell below a certain price on a product on Amazon. I am storing products, sellers, and violations in the database. I am attempting to display the number of sellers who are violating within a 24 hour period. Rather than displaying the number of sellers violating, I am receiving the total number of violations.
ViolationsRepository.php
public function countNumberOfSellersInViolationsForVendorInLast24Hours($vendorId)
{
$select = "SELECT DISTINCT COUNT(
CASE
WHEN v.source = 'amazon' THEN
(SELECT DISTINCT s.id
FROM seller_info_amazon AS sai
LEFT JOIN sellers_amazon AS sa ON sa.amazon_id = sai.id
LEFT JOIN sellers AS s ON sa.seller_id = s.id
WHERE sai.unique_id = v.seller_id_amazon AND s.id IS NOT NULL
LIMIT 1)
WHEN v.source = 'ebay' THEN
(SELECT s.id
FROM sellers AS s
WHERE s.id = v.seller_id_ebay
LIMIT 1)
WHEN v.source = 'google' THEN
(SELECT s.id
FROM sellers AS s
WHERE s.id = v.seller_id_google
LIMIT 1)
END)
FROM
violations AS v
";
$timeLimit = new \DateTime('24 hours ago');
$where = " WHERE v.vendor_id = :vendorId AND v.last_scout_date >= :timeLimit \n";
$query = $this->getEntityManager()->getConnection()->prepare($select . $where );
$query->bindValue(':vendorId', $vendorId);
$query->bindValue(':timeLimit', $timeLimit->format("Y-m-d h:i:s"));
$query->execute();
return $query->fetchColumn();
}
sellers_amazon TABLE
seller_id amazon_id
violations TABLE
id vendor_id seller_id_amazon last_scout_date source
seller_info_amazon TABLE
id unique_id name
sellers TABLE
id originating_vendor_id name
Solved this - SELECT COUNT(DISTINCT ... instead of SELECT DISTINCT COUNT( ....

How to format date in Query Statement Mysql?

I'm using php with Mysql and I need to run a specific query when user selects month and year in a date_field.
This query returns all records created by the month/year selected by user and I don't want relate days in a clause where inside the select.
Since I need only records from month/year select, is there any ways how can I define inside the select only month/year?
Here is my Mysql statement with variable selected by user
There are two tables related with inner join so I can 'grab' records with Date:
$quer_mesano = "Select b.name AS Canal
from canal_canalvenda b
inner join meta_meta c On c.canal_canalvenda_id_c = b.id
And c.deleted = 0
where c.periodo = '$month_year' //Here is the date value I just need to put in month/year
And b.deleted = 0
Group by Canal order by 1";
Can any one help me?
This is very easy. Use DATE_FORMAT. Just change the Sql statement like this:
$quer_mesano = "Select b.name AS Canal
from canal_canalvenda b
inner join meta_meta c On c.canal_canalvenda_id_c = b.id
And c.deleted = 0
where DATE_FORMAT( c.periodo, '%Y-%m' ) = '$month_year' //Just put DATE_FORMAT
And b.deleted = 0
Group by Canal order by 1";
DATE_FORMAT() you can use as shown below
$quer_mesano = "Select b.name AS Canal
from canal_canalvenda b
inner join meta_meta c On c.canal_canalvenda_id_c = b.id
And c.deleted = 0
where DATE_FORMAT( c.periodo, '%Y/%m' ) = '$month_year'
And b.deleted = 0
Group by Canal order by 1";
For month you have different types -
%M Month name
%m Month, numeric (00-12)
and for year -
%Y Year, four digits
%y Year, two digits
I convert the month year to YYYY-MM formate where it can be compared with the db.
$quer_mesano = "Select b.name AS Canal
from canal_canalvenda b
inner join meta_meta c On c.canal_canalvenda_id_c = b.id
And c.deleted = 0
where DATE_FORMAT( c.periodo, '%Y-%m' ) = '" . date("Y-m", strtotime($month_year)) . "' //Here is the date value I just need to put in month/year
And b.deleted = 0
Group by Canal order by 1";

Use of COUNT twice in PHP MySQL Left Join

I have the following COUNT functionality working successfully in this query. I'd like to issue the exact same COUNT/Left Join functionality on another table (same format) called HTG_ScheduledActual
This works:
$query_WADAHTG_TechProps = "SELECT
HTG_TechProps.EmpNumber, HTG_TechProps.EmpFirstName, HTG_TechProps.EmpLastName, HTG_TechProps.Veh_Number,
COUNT(HTG_ScheduleRequest.ID) AS current_job FROM HTG_TechProps
LEFT JOIN HTG_ScheduleRequest ON HTG_TechProps.EmpNumber = HTG_ScheduleRequest.SSR
AND (HTG_ScheduleRequest.ScheduleDateOriginal = CURDATE()
OR HTG_ScheduleRequest.ScheduleDateCurrent = CURDATE()
OR HTG_ScheduleRequest.ScheduleDateExact = CURDATE() ) GROUP BY HTG_TechProps.EmpNumber
ORDER BY HTG_TechProps.EmpNumber ASC
";
I try to insert a second COUNT using AND and it breaks the query. I have bad feeling I can't issue two COUNT in the same query? How is the best way to overcome this?
$query_WADAHTG_TechProps = "SELECT
HTG_TechProps.EmpNumber, HTG_TechProps.EmpFirstName, HTG_TechProps.EmpLastName, HTG_TechProps.Veh_Number,
COUNT(HTG_ScheduleRequest.ID) AS current_job FROM HTG_TechProps
LEFT JOIN HTG_ScheduleRequest ON HTG_TechProps.EmpNumber = HTG_ScheduleRequest.SSR
AND (HTG_ScheduleRequest.ScheduleDateOriginal = CURDATE()
OR HTG_ScheduleRequest.ScheduleDateCurrent = CURDATE()
OR HTG_ScheduleRequest.ScheduleDateExact = CURDATE() ) GROUP BY HTG_TechProps.EmpNumber
AND COUNT(HTG_ScheduleActual.ID) AS actual_job FROM HTG_TechProps
LEFT JOIN HTG_ScheduleActual ON HTG_TechProps.EmpNumber = HTG_ScheduleActual.SSR
AND (HTG_ScheduleActual.ScheduleDateOriginal = CURDATE()
OR HTG_ScheduleActual.ScheduleDateCurrent = CURDATE()
OR HTG_ScheduleActual.ScheduleDateExact = CURDATE() ) GROUP BY HTG_TechProps.EmpNumber
ORDER BY HTG_TechProps.EmpNumber ASC
";

Incorrect MySQL query update

I would like to filtering database records if there is duplicate records I will mark the records as deleted = 1. Unfortunately I'm not able to update my records correctly, I did try use limit 1 for updating the records but I only update 1 record only and if I didn't use the limit 1 it will update entire records.
The above is my database table, what I need to do is, assume there is bunch of records with different point_id and I filtered to 1 only. Now I would like to query the records sort by date ASC and update all the records to deleted = 1 expect the last record.
Here is my source code. The problem I facing now is it will update all the records, and if I using LIMIT 1 it only will update 1 record only.
while($total > 1){
$total--;
$sql = sprintf("SELECT *
FROM customers_profiles_game_logs
WHERE point_id='$points_filter_row[point_id]'
AND customer_id='$sql_customer_row[customer_id]'
ORDER BY date_created ASC");
$query = mysql_query($sql) or die(mysql_error());
$row = mysql_fetch_array($query);
$num_rows = mysql_num_rows($query);
for ($i = 1; $i < $num_rows; $num_rows--) {
echo $sqli = sprintf("UPDATE customers_profiles_game_logs
SET deleted='1'
WHERE customer_id='$sql_customer_row[customer_id]'
AND point_id='$row[point_id]' LIMIT 1");
mysql_query($sqli) or die(mysql_error());
}
}
You can have a subquery which gets the record to be updated and join it with the table itself, eg.
UPDATE customers_profiles_game_logs a
INNER JOIN
(
SELECT customer_id, MIN(date) date
FROM customers_profiles_game_logs
WHERE customer_id = 1 -- <== ID HERE
) b ON a.customer_id = b.customer_id
AND a.date = b.date
SET a.deleted = 1
if you remove the WHERE clause inside the subquery, all the first record for each customer will be updated.
you need this:
UPDATE customers_profiles_game_logs a
INNER JOIN
(
SELECT customer_id, MIN(date) date
FROM customers_profiles_game_logs
WHERE customer_id = 1 -- <== ID HERE
) b ON a.customer_id = b.customer_id
SET a.deleted = 1
http://sqlfiddle.com/#!2/6c440/1
another style:
UPDATE customers_profiles_game_logs a
INNER JOIN
(
SELECT customer_id, MIN(date) date
FROM customers_profiles_game_logs
) b ON a.customer_id = b.customer_id
SET a.deleted = 1
http://sqlfiddle.com/#!2/88e7c/1

Categories