I have a table called payment which adds all the payment entries. I have field in payment table as customer_id which refers to the customer id in the customer table.
There is a field called flag where I store 1 or 0 based on their payment status. If they paid the full amount they flag will be 0 and if there is a balance the flag wil be 1
There is another field in payment table, added_on, which is a timestamp
I want to fetch out the latest added row of all the customer_id(in the payment table) who have flag 1(pending payment)
I tried fetching from the payment table like this
$rResult = mysql_query("select * from payment where flag='1'")
and then looped like this
while ($aRow=mysql_fetch_object($rResult))
{
//fetch out the customer id like this
$customer= $aRow->customer_id;
$pay_quer = mysql_query("select*from payment where customer_id='$customer'");
}
I know it is long to do this..is there any shorter way to do it with one query?
The results are not coming as I expected too. :(
SELECT p.*
FROM
payment AS p
JOIN
( SELECT customer_id
, MAX(added_on) AS max_added_on
FROM payment
WHERE flag='1'
GROUP BY customer_id
) AS g
ON g.customer_id = p.customer_id
AND g.max_added_on = p.added_on
ORDER BY p.added_on DESC
or (it's not clear what you want exactly nor how the flag is used). This will show different results, only those customers that their latest row in the payment has flag=1:
SELECT p.*
FROM
payment AS p
JOIN
( SELECT customer_id
, MAX(added_on) AS max_added_on
FROM payment
GROUP BY customer_id
) AS g
ON g.customer_id = p.customer_id
AND g.max_added_on = p.added_on
WHERE p.flag='1'
ORDER BY p.added_on DESC
I don't know the name of your table and fields but you get the point:
SELECT *
FROM payment
JOIN customer ON payment.customer_id = customer.customer_id
WHERE payment.flag = '1'
ORDER BY payment.added_on ASC;
This will contain all information about the customer related the payment sorted by the latest first.
Why not just use one select statement and loop through the results instead?
SELECT customer_id FROM payment WHERE flag='1' ORDER BY added_on DESC
Hopefully this will get all customers who have a balance in order of 'added_on'. =)
Like the answer below, you can also add an 'AND' to further cut down your results.
Simply order your select statement:
Select * from payment where flag = '1' and customer_id='$customer' order by YourTimeStempFieldHere
You can change the order direction by adding "desc" or "asc" behind your timestemp field.
You can also limit the result with the mysql LIMIT 0,1 operator. If you do that, you dont have to do a while loop.
use this to order by time added.
$rResult = mysql_query("select * from payment where flag='1' ORDER BY added_on DESC");
also
while ($aRow=mysql_fetch_object($rResult))
{
//fetch out the customer id like this
$customer= $aRow->customer_id;
$field2 = $aRow->field2 ;
$field3 = $aRow->field3 ;
$field3 = $aRow->field4 ;
}
there is no need for the second query. you have already got the values in the for loop
Related
I have a custom table "orders" in which I save orders data.
| id | user_id | product
In this way, I get data from it.
$orders = $wpdb->get_results(
"
SELECT *
FROM sbgf_pl_orders
ORDER BY ID DESC
LIMIT 500
");
foreach ( $orders as $order ){
echo $order->id;
}
I want to link my request with user_meta table so that I would get orders from those users whose profile has a specific delivery method as suer meta "shippment_method".
I tried this, but this request overloads my site
$orders = $wpdb->get_results(
"
SELECT *
FROM sbgf_pl_orders, sbgf_user_meta
WHERE sbgf_user_meta.shipping_method = '1' AND sbgf_user_meta.user_id=sbgf_user_meta.user_id
ORDER BY ID DESC
LIMIT 500
");
foreach ( $orders as $order ){
echo $order->id;
}
You are not joining the tables properly :
AND sbgf_user_meta.user_id=sbgf_user_meta.user_id
This condition will always be true, and your join results in a cartesian product between users and orders having shipping method 1.
Also, you should always use explicit joins instead of old-school, implicit joins, as explained for example in this SO answer.
Finally, it is also a good practice to alias the tables in the query, and to prefix the columns with these aliases. This makes the query easier to read and maintain, and avoid ambiguity when column names conflict.
Your query should probably look like :
SELECT *
FROM sbgf_pl_orders ord
INNER JOIN sbgf_user_meta usr ON usr.shipping_method = 1 AND usr.user_id = ord.user_id
ORDER BY ord.ID DESC
LIMIT 500
#GMB thank you for the idea. I guessed how to do it right
$orders = $wpdb->get_results(
"
SELECT *
FROM sbgf_pl_orders ord
INNER JOIN sbgf_usermeta m1 ON (ord.user_id = m1.user_id AND m1.meta_value = '1'
ORDER BY ord.ID DESC
LIMIT 500
"
);
I am new to PHP and SQL; I am writing a SQL query to display records with the following logic:
There are 9 cells in sql table. I want to search records using combinations of 3 parameters. That are search between 2 dates, search in location and search in property category type.
Search criteria looks like this:
Date From : _________(date picker) - Date Till:______________(date picker)
Sales Agent : Dropdown ( dehi, mumbai,.....,)
Mobile : __________ (text)
Results Combination Required:
a. All 3 combination True - (User Fills the date, sales agent, mobile.)
b. Either of the combination is True. (User only fills either of one parameter.)
c. Only 2 Combination are True. (User fills 2 parameter combination ie, date and mobile(or) mobile & sales agent (or) sales agent & date)
Problem: I'm not able to do only one combination.
Here is my SQL query and page syntax:
if(isset($_POST["submit"]))
{
$date11=$_POST["date1"];
$date22=$_POST["date2"];
$salesagent1=$_POST["salesagent"];
$mobile1=$_POST["mobile"];
$result = "select
ordertable.order_date,
ordertable.order_id,
customer.cust_name,
customer.cust_mobile,
customer.cust_email,
customer.cust_city,
ordertable.quantity,
ordertable.total,
orderstatus.order_sta,
salesagent.name
from customer inner join ordertable
on customer.custid=ordertable.cust_id inner join salesagent
on salesagent.said=ordertable.sales_id inner join orderstatus
on orderstatus.id= (select order_statusid from orderhistory where order_id1= ordertable.order_id order by date_added desc limit 1)
where (ordertable.order_date between '$date11' and '$date22') or (customer.cust_mobile='$mobile1') or (ordertable.sales_id='$salesagent1')
order by ordertable.order_id desc";
$records=mysqli_query($CON,$result);
Set null or whatever you choose to do, to each parameters when it is empty:
$result = "select
ordertable.order_date,
ordertable.order_id,
customer.cust_name,
customer.cust_mobile,
customer.cust_email,
customer.cust_city,
ordertable.quantity,
ordertable.total,
orderstatus.order_sta,
salesagent.name
from customer inner join ordertable
on customer.custid=ordertable.cust_id inner join salesagent
on salesagent.said=ordertable.sales_id inner join orderstatus
on orderstatus.id= (select order_statusid from orderhistory where order_id1= ordertable.order_id order by date_added desc limit 1)
where ('$date11' IS NULL OR '$date22' IS NULL OR ordertable.order_date between '$date11' and '$date22') AND ('$mobile1' IS NULL OR customer.cust_mobile='$mobile1') AND ('$salesagent1' IS NULL OR ordertable.sales_id='$salesagent1')
order by ordertable.order_id desc";
I found the following mysqli query on the internet. It displays top 3 sold cars
//create conection with mysql database.
$conn = mysqli_connect("localhost","root","","cars");
//query
$select = "SELECT ord.*, sum(amount) as amt from orders as ord GROUP BY id_car order by amt desc limit 0,3";
$data = mysqli_query($conn,$select);
This query works fine but I would like if anyone can explain me this first section of the query: SELECT ord.*,
It seems like "ord" refers to orders but is it the same as saying: SELECT * FROM orders??
See table in the screenshot image
orders table
In the query there is orders as ord this gives the orders table an 'alias' of the orders table, so ord.* means orders.*
It is a bit redundant in this query to be honest, mainly used if there are multiople tables in a query :)
For this query you can simply do:
$select = "SELECT *, sum(amount) as amt from orders GROUP BY id_car order by amt desc limit 0,3";
Let's break it down:
a) Select all fields from table named ord which will be defined in c)
SELECT ord.*,
b) Select sum of column amount and name it amt
sum(amount) as amt
c) Use table orders for the query and define an alias name ord for that table, see a)
from orders as ord
It is same as select * from tableName,it will fetch all columns from table.But alias Name is given for the table. Using alias Name is best practices for joining the multiple tables.
since you are using single table you can do this also.
SELECT *, sum(amount) as amt from orders as ord GROUP BY id_car order by amt desc limit 0,3
To preface this question - I know I'm missing something really obvious here but it is Friday afternoon!
I'm trying to COUNT to number of times certain values appear within the same column and produce a table of the results.
Here's my code so far:
MYSQL
SELECT COUNT(order_status) as printed
FROM orders WHERE order_status = 'Printed Order'
UNION
SELECT COUNT(order_status) as charged
FROM orders WHERE order_status = 'Charged Order'
UNION
SELECT COUNT(order_status) as exchanged
FROM orders WHERE order_status = 'Exchanged Order'
UNION
SELECT COUNT(order_status) as refunded
FROM orders WHERE order_status = 'Refunded Order'
UNION
SELECT COUNT(order_status) as cancelled
FROM orders WHERE order_status = 'Cancelled Order'
GROUP BY order_status
Result of the above query
printed
-------
224
19190
593
2618
2899
The code is producing the correct figures, however, I would prefer the result to look as follows:
Desired result
printed - 224
charged - 19190
exchanged - 593
refunded - 2618
cancelled -2899
This way I can easily reference them via associative array call i.e. $order_status['printed']
Any help would be great.
Add a column specifying the type. The easiest way is to use group by:
select order_status, count(*)
from orders o
group by order_status;
If you use PDO, set the fetch mode to create associative arrays by default by:
$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
try:
SELECT order_status, COUNT(order_status) as printed
FROM orders WHERE order_status = 'Printed Order'
GROUP BY order_status
i have one table named users. In this table i have one column named credits(not unique).
Now i want the second highest user accroding to the users credits. If the credits field is unique thenmy below query is working fine
SELECT * FROM users ORDER BY credits DESC LIMIT 1 , 1
But , if the users credit is not unique then its create problem for retrive me data
suppose,
mack has 200 credits
jack has 200 credits
rock has 150 credits
when i has this types of record then,in output of this query i want the rock record not jack
can anyone help me to find out the correct value ?
thanks in advance
SELECT a.*
FROM users a
INNER JOIN
(
SELECT DISTINCT credits
FROM users
ORDER BY credits desc
LIMIT 1,1
) b ON a.credits = b.credits
SQLFiddle Demo
Hope this helps (first get second highest credits then find the users having those that credit andselect one from the top`. This will retrieve one user having second highest credit):
SELECT * FROM users
WHERE credits = (SELECT distinct credits FROM users
ORDER BY credits DESC LIMIT 1,1)
LIMIT 1;
EDIT: If you also want to select within users having same score then use the appropriate filter/sorting condition e.g. to select rock between rock and jenni, you could have another ordering base on name(assuming name is the column having names)
SELECT * FROM users
WHERE credits = (SELECT distinct credits FROM users
ORDER BY credits DESC LIMIT 1,1)
ORDER name desc
LIMIT 1;
To get both rock and jenni, just remove the limit from the end and update the inner limit e.g:
SELECT * FROM users
WHERE credits = (SELECT distinct credits FROM users
ORDER BY credits DESC LIMIT 1, 1);
try this
Select * FROM users
Where Credits < (Select Max(Credits) From Users)
ORDER BY credits DESC LIMIT 1;