I have this code:
select count(distinct affiliate_orders_id) as count
, sum(affiliate_value) as total
, sum(affiliate_payment) as payment
from " . TABLE_AFFILIATE_SALES . " a
left join " . TABLE_ORDERS . " o on (a.affiliate_orders_id = o.orders_id)
where a.affiliate_orders_id = o.orders_id
and o.orders_status >= " . AFFILIATE_PAYMENT_ORDER_MIN_STATUS . "
";
$affiliate_sales_query= tep_db_query($affiliate_sales_raw);
$affiliate_sales= tep_db_fetch_array($affiliate_sales_query);
So, $affiliate_sales['total'] = 128000 when in fact it should be 32000 becuase there are multiple affiliate_values and affiliate_orders_id. The affilaite_values some have the same values so these cannot be distinct. affilaite_orders_id have all unique values but there are multiple rows of this and needs to be distinct. Then the affiliate_values has to sum up based on the distinct rows of affiliate_orders_id to get an accurate sum.
I'm trying to get the sum of all affiliate_values bused on how many distinct affiliate_orders_id are in the table.
Based on your update I think this will get you what you're looking for. You need to use a subQuery
SELECT COUNT(a) COUNT, SUM(av) total, SUM(ap) aptotal
FROM (
SELECT affiliate_orders_id a, affiliate_value av, SUM(affiliate_payment) AS ap
from " . TABLE_AFFILIATE_SALES . " a
left join " . TABLE_ORDERS . " o on (a.affiliate_orders_id = o.orders_id
GROUP BY affiliate_orders_id, affiliate_value)
where a.affiliate_orders_id = o.orders_id
and o.orders_status >= " . AFFILIATE_PAYMENT_ORDER_MIN_STATUS . ") a
Now this leads to a bigger question. Are you missing a join condition in your tables? Typically you shouldn't have duplicate date returned in a query, so I would suggest double checking your query is joining properly first.
Related
So I am trying to pull information about business listings from a wordpress database. The information is stored in the wp_posts table and the wp_postmeta table where all of the additional business information is listed.
The wp_postmeta table saves data like this: each piece of data has it's own row, the information is not stored as a serialized array all in one row.
Here is my database query so far:
$wpdb->get_results(
" SELECT * FROM " . $wpdb->posts .
" LEFT JOIN " . $wpdb->postmeta .
" ON " . $wpdb->posts . ".ID = " . $wpdb->postmeta . ".POST_ID" .
" WHERE " . $wpdb->posts . ".POST_TYPE = 'lv_listing' " .
" AND " . $wpdb->posts . ".POST_STATUS = 'publish' " .
" GROUP BY " . $wpdb->posts . ".ID");
Currently, each set of results gives me only one row from the wp_postmeta table, where I am expecting like 20 rows that should match the ID I am grouping by.
What am I doing wrong?
As per my understanding ,can you execute a query in the MySQL database and check if the Data is coming as per your req or not in the database .
Below is the syntax of the left outer join
SELECT column_name(s)
FROM table1
LEFT JOIN table2 ON table1.column_name = table2.column_name;
i am trying to write a query which will help me recover class, batch, and institution details from db
so far i have managed to make the following work:
SELECT
gallery.path_url AS insimage,
r3.*
FROM
gallery
INNER JOIN (
SELECT
institution.id AS insid,
institution.ProfileImageID,
institution.`name` AS insname,
institution.Locality AS inslocality,
institution.RegistrationFee AS ins_reg_fee,
institution.IsTrail AS ins_is_trail,
institution.LatLong AS latlong,
r2., activity.`name` AS activityname
FROM
institution
INNER JOIN (
SELECT
class., count() AS batch_count,
r1.
FROM
class
INNER JOIN (
SELECT
batch.ID AS batch_id,
batch.ClassID AS class_id,
batch.LevelID AS level_id,
batch.agegroupID AS agegroup_id,
count(*) AS num_batches,
min(Price) AS min_price,
max(Price) AS max_price
FROM
batch,
batchstarttimes
WHERE
batch.ID = batchstarttimes.BatchID
AND batchstarttimes.StartTime BETWEEN '" . $sttime . "'
AND '" . $endtime . "'
GROUP BY
batch.ID
) AS r1
WHERE
r1.class_id = class.ID
GROUP BY
r1.class_id
) AS r2 ON r2.institutionid = institution.id
INNER JOIN activity ON activity.id = r2.activityid
WHERE
activity.`name` LIKE '%" . $searchterm . "%'
AND institution.Locality LIKE '%" . $locality . "%'
AND institution.StatusID = 1
AND level_id = 1
AND agegroup_id = 5
) AS r3 ON r3.ProfileImageID = gallery.ID
I am stuck when i try to add two more filters batch.LevelID and batch.agegroupID
any way i can get help or someone point me to a sql visualizr tool will be helpful.
In your WHERE clause, replace:
AND level_id = 1
AND agegroup_id = 5
with:
AND batch.LevelID = CASE WHEN " . $levelID . " = 0 THEN batch.LevelID ELSE " . $levelID . " END
AND batch.agegroupID = CASE WHEN " . $ageGroupID . " = 0 THEN batch.agegroupID ELSE " . $ageGroupID . " END
The point is to compare batch.LevelID and batch.agegroupID against themselves if you want to ignore them for the filtering (this way they'll always be true) or compare them against $levelID and $ageGroupID values for specific rows.
Also, it's not recommended to use the variables directly in the query, as it's vulnerable to SQL injections attacks. Read about prepared statements here.
I have a query and i want random result on advertisement table. Advertise table have own id but when i use RAND(advertise.id) it won't work and i don't know how it will. I am using laravel framework so if possible i can use PHP also to show random advertise result. Here is code can anyone tell me where i use RAND() Mysql function.
SELECT providers.id,
adv__managements.id AS 'adv_id',
adv__managements.images,
adv__managements.categories,
adv__managements.subcategories,
adv__managements.title,
adv__managements.description,
adv__managements.role,
adv__managements.plan_id,
userinformation.user_id,
userinformation.zip_code,
plans.active
FROM userinformation INNER JOIN providers ON userinformation.user_id = providers.user_id
INNER JOIN adv__managements ON adv__managements.range = providers.range
INNER JOIN plans ON plans.user_id = userinformation.user_id
where GetDistance('km'," . doubleval($info->lat) . ", " . doubleval($info->lon) .", " . doubleval(\Auth::user()->userinfo->latitude) . ", " . doubleval(\Auth::user()->userinfo->longitude) . ") < providers.range AND plans.active = 1 LIMIT 3
And can anyone tell how to convert this query into laravel ?
I have the following straightforward query which is part of a garbage collection script. The script is supposed to delete unused shopping carts. A cart is unused when it was updated more than 24 hours ago and is not attached to an order or a user.
$query = "SELECT comm_cart.id AS `cart_id`, (" . time() . " - comm_cart.update_date) AS `diff`, COUNT(comm_orders.cart_id) AS `c1`, COUNT(comm_users.cart_id) AS `c2` " .
"FROM `comm_cart` " .
"LEFT JOIN `comm_orders` ON comm_cart.id=comm_orders.cart_id " .
"LEFT JOIN `comm_users` ON comm_cart.id=comm_users.cart_id " .
"GROUP BY comm_cart.id ";
"HAVING `diff`>86400 AND `c1`=0 AND `c2`=0";
The query finds too many carts: it also tags the ones that have a c1>0 or c2>0 and I can't figure out why. Any clues?
I suspect that you are joining along two different dimensions. The easy fix is to use distinct:
SELECT comm_cart.id AS `cart_id`, (" . time() . " - comm_cart.update_date) AS `diff`,
COUNT(DISTINCT comm_orders.cart_id) AS `c1`, COUNT(DISTINCT comm_users.cart_id) AS `c2` " .
The better solution would be to use not exists for these two conditions:
FROM comm_carts cc
WHERE not exists (select 1 from comm_orders co where cc.id = co.cart_id )
not exists (select 1 from comm_users cu where cc.id = cu.cart_id )
You don't even need the group by, an isnull condition in the where would work wonders, of course I suggest using Gordon's suggestion of the not exists, but if you want the minimum change this would be is.
SELECT
comm_cart.id AS `cart_id`,
(UNIX_TIMESTAMP() - comm_cart.update_date) AS `diff`
FROM `comm_cart`
LEFT JOIN `comm_orders`
ON comm_cart.id=comm_orders.cart_id
LEFT JOIN `comm_users`
ON comm_cart.id=comm_users.cart_id
WHERE
comm_orders.cart_id IS NULL
AND
comm_users.cart_id IS NULL
Oh, and I've used UNIX_TIMESTAMP() instead of the PHP time function, same effect, but this avoids mixing PHP and SQL.
if you only want to get data with c1=0 and c2=0 then you need to write a where condition instead of having before group by,
$query = "SELECT comm_cart.id AS `cart_id`, (" . time() . " - comm_cart.update_date) AS `diff`, COUNT(comm_orders.cart_id) AS `c1`, COUNT(comm_users.cart_id) AS `c2` " .
"FROM `comm_cart` " .
"LEFT JOIN `comm_orders` ON comm_cart.id=comm_orders.cart_id " .
"LEFT JOIN `comm_users` ON comm_cart.id=comm_users.cart_id " .
" where c1=0 and c2 =0 and diff >86400 GROUP BY comm_cart.id;
I have a question how do I add a query for a date range here in my MySQL query. The date is generated only.
Here is my Query:
SELECT TS.id AS TSid, employeeid, `date` AS date_d, TS.TI1 AS TI1, TS.TO1 AS TO1,
CONCAT(E.lastName,', ',E.firstName,' ',E.middleInitial,'.') AS 'fullname',
(TIME_TO_SEC(CAST(TS.`TI1` AS time))/3600) AS 'timeinint',
(TIME_TO_SEC(CAST(TS.`TO1` AS time))/3600) AS 'timeoutint',
E.startDate, C.companyName, B.branchName,
R.mon, R.tue, R.wed, R.thu, R.fri, R.sat, R.sun
FROM timeschedule AS TS
LEFT JOIN employee AS E ON TS.employeeid = E.id
LEFT JOIN company AS C ON E.companyid = C.id
LEFT JOIN branch AS B ON E.branchid = B.id
LEFT JOIN restday AS R ON R.id = E.restDayid
WHERE TS.`show` = '1'
ORDER BY employeeid ASC
HEre is how I get the input:
$mfrom = $this->input->get('mfroma'); //From: Month
$yfrom = $this->input->get('yfroma'); //From: Year
$yto = $this->input->get('ytoa'); //To : Year
With the fields you've specified (from month and year and to year) you can add these conditions into your WHERE clause. I'm going to use the E.startDate field for this example:
$sql = "-- your query here...
WHERE
TS.`show` = '1'
AND MONTH(E.startDate) >= " . $mfrom . "
AND YEAR(E.startDate) BETWEEN " . $yfrom . " AND " . $yto . "
ORDER BY employeeid ASC";
Docs:
- MONTH()
- YEAR()
Note: PHP parses variables inside double quotes, but I personally prefer to keep PHP variables outside of them.