Looping through multiple SQL queries - php

I have an SQL table of tens of thousand of orders, each one is from around 100 different companies. I want to do a total for each company on an admin web page.
Am I supposed to loop and do 100 queries (one for each company) - eg 'SELECT SUM(order_amount) FROM orders WHERE company = XXX' or do one query to show all orders to loop through them and add each order to an array key of a company, eg company_array[company] += order_amount

With a structure like this :
companies
--------------
company_id
company_name
orders
--------------
order_id
order_company # Foreign key to companies.company_id
order_amount
You can do an unique SQL request like that :
SELECT ALL company_name, SUM(order_amount) AS company_amount
FROM orders INNER JOIN companies ON order_company = company_id
GROUP BY company_name
With PHP :
$sql = <<<SQL
SELECT ALL company_name, SUM(order_amount) AS company_amount
FROM orders INNER JOIN companies ON order_company = company_id
GROUP BY company_name
SQL;
$result = $pdo->query($sql)->fetchAll();
// Now you can loop $result
print_r($result);

Related

How to properly join tables with a many to one relationship

I have six tables
The main table Orders is an encrypted table containing orders that customers have made.
The second table is a hash table for the Orders table. OrdersHash.
The remaining four tables are store tables that all have the same structure. StoreA, StoreB, StoreC, & StoreD.
Orders Table
orderId | rest of row...
OrdersHash Table
orderId | orderIdHash | rest of row..
The four store tables all share this structure.
orderIdHash | customerId | rest of row..
Using only the customerId I am trying to query the four store tables to see if any of the store tables contain the customerId. If the customerId is found on any of the four store tables I want to use the orderIdHash to get me back to the original Orders table and return the row for any orders that were found.
If I use a the customerId for Mike I would expect row 1 from the Orders table.
This is what I have tried so far.
"SELECT
o.dateShipped AS orderShipped,
o.shipped AS shipped,
o.recieved AS recieved
FROM Orders o
JOIN OrdersHash oHash
ON o.orderId = oHash.orderId
JOIN StoreA a
ON ohash.orderIdHash = a.orderIdHash
JOIN StoreB b
ON ohash.orderIdHash = b.orderIdHash
JOIN StoreC c
ON ohash.orderIdHash = c.orderIdHash
JOIN StoreD d
ON ohash.orderIdHash = d.orderIdHash
WHERE
a.customerId = :customerId1
OR b.customerId = :customerId2
OR c.customerId = :customerId3
OR d.customerId = :customerId4";
**customerId 1,2,3,4 are all the same value.. I have to use a different name for binding in PDO.
This will return a result but it seems to return the same row from Orders for every row in a store with a matching orderIdHash when I just need the one record from the Orders table.
Thank you in advance for your help.
It seems you probably want to UNION the store results and then JOIN that to the Orders table. By using UNION rather than UNION ALL, we can select only the distinct orderIdHash values, ensuring we only get one row for each Order in the result table. Something like this:
SELECT o.dateShipped AS orderShipped,
o.shipped AS shipped,
o.recieved AS recieved
FROM (SELECT customerId, orderIdHash
FROM (SELECT customerId, orderIdHash FROM StoreA
UNION
SELECT customerId, orderIdHash FROM StoreB
UNION
SELECT customerId, orderIdHash FROM StoreC
UNION
SELECT customerId, orderIdHash FROM StoreD
) stores
WHERE customerId = :customerId) c
JOIN OrdersHash oHash ON oHash.orderIdHash = c.orderIdHash
JOIN Orders o ON o.orderId = oHash.orderId

Counting values from two tables and returning the result in a single value

How to count value from two tables and return the result in a single value.?
I had two tables named order and affiliate, like below:
order:
order_ID(primary key), order_name, Order_status, affiliate_ID (foreign key)
affiliate:
affiliate_ID (primary key),affiliate_name
Now, I want to count the orders based on affiliate name by comparing the affiliate_ID on order table and affiliate table.
I have tried it like this:
Query
SELECT COUNT(*)
FROM order o
AND (SELECT COUNT (affiliate_name) FROM affiliate a
WHERE a.affiliate_id = O.affilate_id) AS total
It returns an error.
I feel this is what you need
SELECT a.affiliate_ID, a.affiliate_name, COUNT(o.order_ID) as total
FROM order o
LEFT JOIN affiliate a ON o.affiliate_ID = a.affiliate_ID
GROUP BY o.affiliate_ID;
to add WHERE clause, see sample
SELECT a.affiliate_ID, a.affiliate_name, COUNT(o.order_ID) as total
FROM order o
LEFT JOIN affiliate a ON o.affiliate_ID = a.affiliate_ID
WHERE o.affiliate_ID = 3
GROUP BY o.affiliate_ID;
Not sure I understand your question correctly, but is this what you're looking for ?
SELECT *, COUNT(*) as total
FROM order o
JOIN affiliate a ON a.affiliate_id = o.affiliate_id
GROUP BY o.affiliate_id
Otherwise, provive sample & desired result example please.

How to limit SQL to one record based on ID

I have a table called bids, that have multiple rows.
these all have unique IDs however they have a listingID as well, so everytime it inserts it inserts a new row but with that listingID.
I'm trying to only return one unique result for the ListingID as appose to all the bids in the table , I tried SELECT DISTINCT and group by, but both didn't seem to work.
At the moment this is printing all the records from the table 'bids'
I would like to only print the last record for the listingID column.
$bids = $this->db->query("SELECT bidID,listingID, listing_title, bid_date, username,amount, starting_, sold, vintage, bottles, size, cases, sold_date, bid_type,
FORMAT(`bin`, 0) AS `bin`,
(CASE
WHEN ( SELECT COUNT(*) FROM bids WHERE bid_listing = listingID )
THEN
(SELECT FORMAT(amount,0) FROM bids WHERE bid_listing = listingID ORDER BY bidID DESC LIMIT 1)
ELSE
FORMAT(`starting_`, 0)
END
) AS `starting`
FROM (`bids`)
JOIN listings ON listingID = bid_listing
JOIN users ON list_uID = userID
WHERE bidder_ID = $userID
ORDER BY bidID DESC");
Try this sql. I used b1.* because I don't know what fields you're trying to return.
$bids = $this->db->query("select b1.* from bids b1
left join bids b2 on (b1.listingID = b2.listingID and b1.bidID < b2.bidID
where b2.bidID is null");

Select records comparing a field from another table

I have three tables
orders
members
products
In orders, I have fields id, mem_id, date, prod_id, status where mem_id coming from members table and prod_id is coming from products table
In members, I have fields mem_id, name, phone, address, city, state, zip, country where country holds id of country from country table
Now, I want to show the records from orders table only for product id 2 and from members from country id 25
I have tried doing:
SELECT o.mem_id, o.prod_id, m.mem_id FROM orders o INNER JOIN members m ON m.mem_id = (SELECT mem_id FROM members WHERE country=25) WHERE o.prod_id=2
But it gives:
Fatal error: Call to a member function fetch_assoc() on a non-object in
So, its not fetching any data and a problem in my query. Please suggest me, Thanks
Join the table using ON condition and apply the where condition like this
SELECT o.mem_id, o.prod_id, m.mem_id
FROM orders o
INNER JOIN members m
ON m.mem_id = o.mem_id
WHERE o.prod_id=2 and m.country=25
You can JOIN the tables on column and specify the condition in WHERE clause, e.g.:
SELECT o.mem_id, o.prod_id, m.mem_id
FROM orders o JOIN members m ON o.mem_id = m.men_id
WHERE o.prod_id = 2 AND m.country = 25;

Querying comma separated field?

I am trying to output a select dropdown options based on a comma separated field where if the user has been assigned an ID of 1 and 2 for example then I want to output the locations id has 1 and 2:
Users table:
id (which equals 1) and usergrouplocid which is a text field with (1,2)
Location Table:
id which auto_increment and a loc_id see iamge below:
My query is as follows:
$query = "SELECT room_location.*, client_room.*, users.* FROM room_location INNER JOIN client_room ON room_location.user_loc_id = client_room.id INNER JOIN users ON room_location.user_loc_id = users.userGroupLocID WHERE 1 IN (userGroupLocID) ORDER BY room_location.location";
The query above works fine but it only outputs where the id of 1 exists in usergrouplocid, so how do I get the query to find if 1, 2, 3 or 4 etc is in the usergrouplocid.
Just in case you really need it sorted now without redesigning your database (which I would)...
$ids = array(1,2,4);
$query = "SELECT room_location.*, client_room.*, users.* FROM room_location INNER JOIN client_room ON room_location.user_loc_id = client_room.id INNER JOIN users ON room_location.user_loc_id = users.userGroupLocID WHERE userGroupLocID REGEXP '(^|,)(".implode('|',$ids).")(,|$)' ORDER BY room_location.location";

Categories