mysqli Table Joining - php

I’m using Ajax to retrieve information from my database. I have no trouble sending to server PHP and getting information back using simple SQL queries. I came across a section that I needed to pull from 2 tables (Same Database) Both in common are column PO. Attached is a picture of an example.
I have been trying to pull everything from one table that meets my condition like Month of, year of and Store. I have been able to JOIN them but not successfully. Closest I ever got is it checks both tables and only returns the data that have matching PO and not the rest of Table 1.
I like for it to retrieve all rows in table one that meet the conditions and if there is a matching PO in table2 join it else continue to retrieve from table1.
Please any help would be grateful

I figured it out. Thank you
$sql = "SELECT * FROM weekly_report LEFT JOIN tracker ON weekly_report.PO = tracker.POt WHERE MONTH(STR_TO_DATE(`Need By Date (Date)`, '%m-%d-%Y')) = '$month' AND YEAR(STR_TO_DATE(`Need By Date (Date)`, '%m-%d-%Y')) = '$year' AND weekly_report.`Ship To Location (Location ID)` LIKE '%$store%' GROUP BY (weekly_report.PO)";

Related

MySQL - Select last rows of LEFT JOIN column based on the fields

I am building a mobile chat web application and I have stuck in a problem. Coming straight to the issue, I have a screen which displays messages list from all users (like WhatsApp). I want to display the last message sent or received between the users in the list (as in the screenshot below). My current query extracts the message from the 1st row for all users right now. That's not what I want.
Little more brief details of what is happening
As you can see in messages table, the fields msg_from and msg_to represents the sender and the receiver respectively. In my data, the messages are transferred between user 1 & 8 and user 1 & 11. For user 1 & 8 the last record fetched should be record 9 which has msg_message Are you there? and similarly, for user 1 & 11 the last record to be fetched would be record 10 which has msg_message Would you like to join?. But currently, for all users the record getting fetched is the 1st record with message How are you?. What changes should my query have to get the desired result? Please have a look at the fiddle below.
Fiddle Here: DB Fiddle
I learned a lot from researching in order to solve this. When grouping, groupBy will take the first row of non-grouped columns (suck as msg_message), so we may order it when joining with the help of a subquery, just like this:
SELECT swp_by, swp_to, msg_from, msg_to, mem_fname, mem_lname, mem_last_activity, msg_message, GREATEST(MAX(msg_time), swipes.swp_date) as msgdate, COUNT(msg_id) as msgcnt FROM swipes
LEFT JOIN
(
SELECT * FROM messages order by msg_time desc -- this is the magic, we use this subquery to order before grouping
)
messages ON
((
messages.msg_from = swipes.swp_by
AND messages.msg_to = swipes.swp_to)
OR (messages.msg_from = swipes.swp_to
AND messages.msg_to = swipes.swp_by
))
solution is in your fiddle: https://www.db-fiddle.com/f/xnh4jiUb8rDLFHpL2gWHrM/5
I think I got expected output

Query selected columns from two tables with a Condition clause

I have two tables-
1) ****Company_Form****
[Contract_No#,Software_Name,Company_Name,Vendor_Code]
2) ****User_Form****
[Contract_No,Invoice_No#,Invoice_Date,Invoice_Amount,Invoice_Submit_Date]
Fields denoted with # and bold are primary keys.
=>The user has to enter a software name for which he wants to get the data of.
=>I have to structure a query in which I have to display the result in the following form:
[Contract#,Software_Name,Company_Name,Invoice_No,Invoice_Date,Invoice_Submission_Date]
Now,
one Contract_No can contain many Invoice_no under its name in
the User Form table.
One Contract_No can occur one time only in
Company_Form table
The retrieved records have to be group by the latest Invoice_Date
I came to the logic that:
I have to first retrieve all the contract numbers with that software
name from Company_Form table.
I have to query that contract number from User_Form table and display
the data for each matched contract no. fetched from Company_Form
table.
The problem is that I am unable to structure a query in SQL that can do the task for me.
Kindly help me in formulating the query.
[PS] I am using SQL with PHP.
I tried a query like:
I tried one approach as :
SELECT a.ContractNo,a.SoftwareName,a.CompanyName,b.InvoiceNo,b.InvoiceDate,b.InvAmount,b.InvoiceSubmitDate
FROM Company_Form as a,User_Form as b
WHERE b.ContractNo IN(SELECT ContractNo FROM Company_Form WHERE
SoftwareName='$Sname') AND a.ContractNo=b.ContractNo;
But I am getting a error that sub query returns more than 1 row.
Can I get help from this?
I am assuming you are attempting to find the most recent price of the user selected software and its corresponding invoice. Here is an approach to do this. If this is tested to your satisfaction, I can add necessary explanation.
select uf.Contract_No#,
cf.Software_Name,
cf.Company_Name,
uf.Invoice_No#,
uf.Invoice_Date,
uf.Invoice_Amount,
uf.Invoice_Submit_Date
from User_Form uf
inner join (
-- Most recent sale of software
select Contract_No#, max(Invoice_Date)
from User_Form
group by Contract_No#
) latest
on (
-- Filter via join for latest match records
uf.Contract_No# = latest.Contract_No#
and uf.Invoice_Date = latest.Invoice_Date
)
inner join Company_Form cf
on cf.Contract_No# = uf.Contract_No#
where cf.Software_name = :software_name
If the requirement allows your sub query to return more than one row, I would suggest you to use IN instead of = in the where clause of your main query.
Please note that I have just looked at the query and have not fully understood the requirements.
Thanks.
I worked around for some time and finally came to the following query which works like a charm
SELECT a.ContractNo,a.SoftwareName,a.CompanyName,b.InvoiceNo,b.InvoiceDate,b.InvAmount,b.ISD
FROM Company_Form as a,User_Form as b
WHERE b.ContractNo IN (SELECT ContractNo FROM Company_Form WHERE SoftwareName='$Sname')
AND a.ContractNo=b.ContractNo;
If anybody needs help in understanding the logic of this query,feel free to comment below.

Select data from one table, arrange by a sum of data from another

A client is looking for a points system to be implemented on her website, I'm struggling to display the users based upon the amount of points collected, I hope somebody may be able to help me out here and point me in the right direction to getting this code to work properly.
I am selecting all data from ap_users and in the code I am also trying to select all data from ap_points although I do not require all the data from either tables, to be specific I only require:
ap_users:
user_id
first_name
last_name
display_img
hub_access
ap_points:
user_id
points_added
I thought that selecting ALL data may be the easiest route, will let you decide.
I am trying to select and display all users where hub_access = '1' and order by the total points_added by highest first. Points are added separately by rows and need to be added up (which is why I have the sum function).
$sql = "SELECT * FROM `ap_users`, `ap_points` WHERE `hub_access` = '1' ORDER BY sum(points_added) DESC";
I also tried configuring it to be specific tables like:
ap_users.hub_access and ORDER BY sum(ap_points.points_added) but these did not work either.
This current code is either showing no results or a single result with no errors displaying? I'm not sure whether I may need to use some kind of Group By function to connect the user_ids from both tables ?
SUM is an aggregating function. You should be grouping by user_id if you want the sum for each user_id.
Something like
SELECT *, sum(points_added) as sum_points FROM app_users
JOIN app_points ON app_users.user_id = app_points.user_id
WHERE `hub_access` = '1'
GROUP BY app_users.user_id
ORDER BY sum_points;
I have not tested that query, but that should give you an idea of the solution.

Return all records of non-given id if just one of those records matches the given id of another field

After searching for a damn long time, I've not found a query to make this happen.
I have an "offers" table with a "listing_id" field and a "user_id" field and I need to get ALL the records for all listing_id's where at least one record matches the given user_id.
In other words, I need a query that determines the listing_id's that the given user is involved in, and then returns all the offer records of those listing_id's regardless of user_id.
That last part is the problem. It's getting all the other user's offer records to return when I'm only providing one user's id and no listing id's
I was thinking of first determining the listing_ids in a separate query and then using a php loop to create a WHERE clause for a second query that would consist of a bunch of "listing_id = $var ||" but then I couldn't bring myself to do it because I figured there must be a better way.
Hopefully this is easy and the only reason it has escaped me is because I've had my head up my ass. Will be happy to get this one behind me.
Thanks for taking the time.
Josh
You could do two queries playing along on the MySQL side, like this:
SELECT * FROM offers WHERE listing_id IN (SELECT listing_id FROM offers WHERE user_id = 1)
If I understand what you are after you should join offers on itself on listingid match and userid = given
select * from offers AS t1
inner join offers AS t2 on t1.listingid = t2.listingid and t1.userid = 1;

PM system - previewing previous PMs

I am working on a PM system where I'd like to have the previous sent PMs for one conversation, listed above the last received PM. But my question is: how do I go about setting up such a table in a database? I toyed for a while about using an id for each specific conversation, but what would the source for that id be? I can't use auto increment (it seems), because I'm using it for the primary "id" column.
Or maybe there's a completely different way I can experiment with the already available columns (id, from, to, subject, message, sent, read, deleted); but how? Please help a lost man out.
You could add a origin_id column to your table that contains the id of the root/original message, or NULL if it's a new discussion (root).
Then you can get the root messages by filtering those than have origin_id = NULL and then group by origin_id to get the message thread.
Okay, so I have got it partly solved...
I used another table containing the one column which holds the subject of the PM. I also have a new column in the regular "pms" table that holds the same ID to be able to join the tables together.
However, when I select all the PMs to show them in the inbox, I have not found a way to group the conversations in order by if they're read or not. I'm currently using this SQL query:
SELECT *
FROM `pms`
JOIN `pm_conversations` ON (pms.ConvID = pm_conversations.ID)
WHERE pms.To='username'
GROUP BY pm_conversations.ID
ORDER BY pms.ID
I came up with this:
SELECT MAX(pms.ID) as pmIDS,
pms.*,
pm_conversations.*
FROM `pms`
JOIN `pm_conversations` ON (pms.ConvID = pm_conversations.ID)
WHERE `To`='".$UserActive."'
GROUP BY pm_conversations.ID
ORDER BY pmIDS DESC

Categories