Select data from table using SQL query - mysql

I have a table name "chat_details" I wanna access only data with green underline according to time, I use the following query
//suppose $user_id = 1;
"SELECT *
FROM chat_details WHERE from_user_id='$user_id' OR to_user_id='$user_id' ORDER BY time DESC"
It fetch all the rows because all rows contain user_id = 1 in one of the column, but i need only green underline rows as compare to red one because green one are latest according to time(column), how can i fetch only these green underlines?

This is one posible query, that should solve your question.
SELECT *
FROM chat_details c
WHERE (c.from_user_id='$user_id' OR c.to_user_id='$user_id')
AND NOT EXISTS (
SELECT 1 FROM chat_details d
WHERE d.from_user_id = c.from_user_id
AND d.to_user_id = c.to_user_id
AND d.time > c.time)
ORDER BY c.time DESC"
Actually I could not test, hope I haven't made a mistake.
The query selects all data as in your query, but only thoose which haven't a newer chat between the two users.
For the EXISTS keyword see http://www.mysqltutorial.org/mysql-exists/

Related

selecting most recent row from joined table in MySQL

I have two tables, Project and Projectnote
There is a one to many relationship between project and projectnote.
I want to be able to list my projects and select the most recent projectnotes based on the id.
Is this possible to do in Mysql query, I can't figure it out.
Thanks for any help!
Edit: so far I have a basic query (below) that joins the two tables. However, this only selects projects where a note exists and I get multiple rows where there are several notes per project.
SELECT `driver_checkins`.*, `driver_trips`.`id` AS `trip_id`, `driver_trips`.`trip_num` AS `trip_num`, `driver_trips`.`status` AS `trip_status`, `driver_trips`.`ride_date` AS `ride_date`, `driver_trips`.`today_date` AS `trip_today_date`, `driver_trips`.`pick_up_time` AS `pick_up_time`, `driver_trips`.`d_time` AS `d_time`, `driver_trips`.`trip_type` AS `trip_type`
FROM `driver_checkins`
LEFT JOIN `driver_trips` ON `driver_trips`.`driver_id` = `driver_checkins`.`driver_id` WHERE `checkin_status` = 1 AND `booking_status` = 0;
Using a GROUP BY clause and the GROUP_CONCAT function should do the trick.
I am assuming that "driver_checkins" is your "Project" table and "driver_trips" is your "Projectnote" table.
SELECT `driver_checkins`.*, GROUP_CONCAT(`driver_trips`.`id`, `driver_trips`.`status` ORDER BY `driver_trips`.id DESC SEPARATOR " --- " LIMIT 3)
FROM `driver_checkins`
LEFT JOIN `driver_trips` ON `driver_trips`.`driver_id` = `driver_checkins`.`driver_id`
WHERE `checkin_status` = 1 AND `booking_status` = 0
GROUP BY `driver_checkins`.id;
This should display id and status for the last 3 driver_trips per driver_checkin, separated by " --- ".
Something to consider: while in many cases ordering by id will work chronologically, it's always better to add a timestamp column (e.g. called created) instead to order by chronologically.

Using results of one query into the next with unlike column names

My Platform is MySql
I have two queries that I need to combine, using the first query as a type of filter for the second query.
Query 1:
SELECT * FROM INVENTORY
WHERE INV_ID = 1
AND FSCL_YR = 2017
From this query we will get results back that includes a column named STR_NBR.
Which we then want to use in the second query as 'If the store number appears in the first query, give me the results where it shows in the second'. The second query tables use the column name SND_LOC_NBR instead of STR_NBR.
Query 2:
SELECT * FROM Transfer A
LEFT JOIN Transfer_Detail B
ON A.XFER_NBR = B.XFER_NBR
WHERE A.XFER_NBR = B.XFER_NBR
AND A.XFER_STAT_IND IN ('S','C')
AND (where the SND_LOC_NBR needs to match STR_NBRs found from Query 1)
Try this:
SELECT * FROM Transfer A
LEFT JOIN Transfer_Detail B
ON A.XFER_NBR = B.XFER_NBR
WHERE A.XFER_STAT_IND IN ('S','C')
AND SND_LOC_NBR IN
(SELECT STR_NBR FROM INVENTORY
WHERE INV_ID = 1 AND FSCL_YR = 2017 )

MySQL Query gets too complex for me

I'm trying to write a MYSQL Query that updates a cell in table1 with information gathered from 2 other tables;
The gathering of data from the other 2 tables goes without much issues (it is slow, but that's because one of the 2 tables has 4601537 records in it.. (because all the rows for one report are split in a separate record, meaning that 1 report has more than 200 records)).
The Query that I use to Join the two tables together is:
# First Table, containing Report_ID's: RE
# Table that has to be updated: REGI
# Join Table: JT
SELECT JT.report_id as ReportID, REGI.Serienummer as SerialNo FROM Blancco_Registration.TrialTable as REGI
JOIN (SELECT RE.Value_string, RE.report_id
FROM Blancco_new.mc_report_Entry as RE
WHERE RE.path_id=92) AS JT ON JT.Value_string = REGI.Serienummer
WHERE REGI.HardwareType="PC" AND REGI.BlanccoReport=0 LIMIT 100
This returns 100 records (I limit it because the database is in use during work hours and I don't want to steal all resources).
However, I want to use these results in a Query that updates the REGI table (which it uses to select the 100 records in the first place).
However, I get the error that I cannot select from the table itself while updateing it (logically). So I tried selecting the select statement above into a temp table and than Update it; however, then I get the issue that I get to much results (logically! I only need 1 result and get 100) however, I'm getting stuck in my own thougts.. I ultimately need to fill the ReportID into each record of REGI.
I know it should be possible, but I'm no expert in MySQL.. is there anybody that can point me into the right direction?
Ps. fixing the table containing 400k records is not an option, it's a program from an external developer and I can only read that database.
The errors I'm talking about are as follows:
Error Code: 1093. You can't specify target table 'TrialTable' for update in FROM clause
When I use:
UPDATE TrialTable SET TrialTable.BlanccoReport =
(SELECT JT.report_id as ReportID, REGI.Serienummer as SerialNo FROM Blancco_Registration.TrialTable as REGI
JOIN (SELECT RE.Value_string, RE.report_id
FROM Blancco_new.mc_report_Entry as RE
WHERE RE.path_id=92) AS JT ON JT.Value_string = REGI.Serienummer
WHERE REGI.HardwareType="PC" AND REGI.BlanccoReport=0 LIMIT 100)
WHERE TrialTable.HardwareType="PC" AND TrialTable.BlanccoReport=0)
Then I tried:
UPDATE TrialTable SET TrialTable.BlanccoReport = (SELECT ReportID FROM (<<and the rest of the SQL>>> ) as x WHERE X.SerialNo = TrialTable.Serienummer)
but that gave me the following error:
Error Code: 1242. Subquery returns more than 1 row
Haveing the Query above with a LIMIT 1, gives everything the same result
Firstly, your query seems to be functionally identical to the following:
SELECT RE.report_id ReportID
, REGI.Serienummer SerialNo
FROM Blancco_Registration.TrialTable REGI
JOIN Blancco_new.mc_report_Entry RE
ON RE.Value_string = REGI.Serinummer
WHERE REGI.HardwareType = "PC"
AND REGI.BlanccoReport=0
AND RE.path_id=92
LIMIT 100
So, why not use that?
EDIT:
I still don't get it. I can't see what part of the problem the following fails to solve...
UPDATE TrialTable REGI
JOIN Blancco_new.mc_report_Entry RE
ON RE.Value_string = REGI.Serinummer
SET TrialTable.BlanccoReport = RE.report_id
WHERE REGI.HardwareType = "PC"
AND REGI.BlanccoReport=0
AND RE.path_id=92;
(This is not an answer, but maybe a pointer towards a few points that need further attention)
Your JT sub query looks suspicious to me:
(SELECT RE.Value_string, RE.report_id
FROM Blancco_new.mc_report_Entry as RE
WHERE RE.path_id=92
GROUP BY RE.report_id)
You use group by but don't actually use any aggregate functions. The column RE.Value_string should strictly be something like MAX(RE.Value_string) instead.

SQL Query Assistance - Left join unexpected result

I have these 2 queries:
$sql = "SELECT *
FROM ultrait_wpl_properties
LEFT JOIN ultrait_wpl_property_types
ON ultrait_wpl_properties.property_type = ultrait_wpl_property_types.id
ORDER BY ultrait_wpl_properties.id ";
$sql2 = "SELECT *
FROM ultrait_wpl_properties, ultrait_wpl_property_types
WHERE ultrait_wpl_properties.property_type = ultrait_wpl_property_types.id
ORDER BY ultrait_wpl_properties.id";
For some odd reason when the IDs are output some are duplicated? By my reseaning these queries should get everything from the table in the first part and join the second table based on the WHERE condition.
<property><id>13</id></property>
<property><id>6</id></property>
<property><id>6</id></property>
<property><id>6</id></property>
<property><id>6</id></property>
<property><id>7</id></property>
This may be slightly unclear but for some reason I'm getting duplicate IDs, all i want really is to be able to access the property type which links to the ID in the second table.
I have tested both queries in phpMyAdmin and they yeild the desired result, however when I use the queries in my php script they return unexpected results.
You are getting one row for each row in table ultrait_wpl_properties. What else do you expect? If it is just one record per type, then you would have to re-write your query accordingly. You select * from both tables. But is it only the type ID you need? Then why join the tables at all?
Get all type IDs:
select id from ultrait_wpl_property_types;
Get all type IDs in table ultrait_wpl_properties:
select distinct property_type from ultrait_wpl_properties;
Get all type data for types in ultrait_wpl_properties:
select * from ultrait_wpl_property_types
where id in (select property_type from ultrait_wpl_properties);
You are getting a Cartesian result in the case the ultrait_wpl_property_types table has multiple records for a single property. Such as a property type could be Type A, Type B, Type C which might be descriptive "types". So a single property would be accounted for each entry.
You might just need to do SELECT DISTINCT, or GROUP BY ultrait_wpl_properties.id to make sure only one record per ID, but with generic "Select * ", I would first try with GROUP BY.

SQL RAND Query selecting all records and not using joined table

Please can someone talk me through a query that I have inherited through a website I am developing.
The query is returning a random group of 5 products based on the category number 56. There is an issue with the query because it is not restricting the selection based on the product on web and product archive conditions.
AND p.product_OnWeb = 1
AND p.product_Archive = 0
The above lines in the query aren't being adhered to. Instead the query is including all products even when they are marked as p.product_Archive=1 (Archived) and p.product_OnWeb = 0 (Not Online)
If someone could point out where I need to make a change I'd be grateful.
The query in full is:-
SELECT c.prdt_cat_rel_Product_ID,
ROUND(RAND() * x.m_id) 'rand_ind'
FROM tbl_prdtcat_rel c,
tbl_products p,
(SELECT MAX(t.prdt_cat_rel_Cat_ID) 'm_id'
FROM tbl_prdtcat_rel t) x
WHERE c.prdt_cat_rel_Cat_ID = 56
AND p.product_OnWeb = 1
AND p.product_Archive = 0
ORDER BY rand_ind
LIMIT 3
Thankyou
First, to make it easier, convert the query to the newer join syntax
SELECT c.prdt_cat_rel_Product_ID, ROUND(RAND() * x.m_id) 'rand_ind'
FROM tbl_prdtcat_rel c,
JOIN tbl_products p ON p.??? = c.???
JOIN (
SELECT MAX(t.prdt_cat_rel_Cat_ID) 'm_id' FROM tbl_prdtcat_rel t
) x ON 1=1
WHERE c.prdt_cat_rel_Cat_ID = 56
AND p.product_OnWeb = 1
AND p.product_Archive = 0
ORDER BY rand_ind
LIMIT 3
You can see that the query doesn't know how to select match records from P based on C, so it grabs them all.. You need to specify how to match tbl_prdtcat records with tbl_product records (replace the ??? in the above with the appropriate fields)
I am guessing each product in p has some sort of field indicating which category it belong to, use this field to match and your query should work...