SQL - Select value with newest date - php

I am trying to select added value "state" with newest date from my table, but only if left join table object is visible. And only once per property and unit in.
What i have done so far:
SELECT propertyUnitEnergyStates.id,
propertyUnitEnergyStates.property_id,
propertyUnitEnergyStates.unit_id,
propertyUnitEnergyStates.type,
propertyUnitEnergyStates.state,
propertyUnitEnergyStates.date,
propertyUnits.visible
FROM propertyUnitEnergyStates
LEFT JOIN propertyUnits
ON propertyUnits.property_id = $propertyID
WHERE propertyUnitEnergyStates.property_id = $propertyID
AND propertyUnitEnergyStates.type = '$name'
AND propertyUnits.visible = 1
GROUP BY propertyUnitEnergyStates.unit_id
ORDER BY propertyUnitEnergyStates.date DESC
What I am getting now is result where every propertyUnits.visible is 1. Even if in table is set to zero.
Object from propertyUnits. As you can see the value visible is 0 but i am getting 1.
Right now i noticed that, the "state" value which i want to be the newest is not the newest.
As you can see i have in my result for unit_id 5 value 853, but in the table propertyUnitEnergyStates is the newest value 400.

Okay. Let's try like this.
WITH ranked_state AS (
SELECT us.*, ROW_NUMBER() OVER (PARTITION BY unit_id ORDER BY date DESC) AS rn
FROM propertyUnitEnergyStates us
WHERE us.type = '$name' AND us.property_id = $propertyID
)
SELECT ranked_state.id,
ranked_state.property_id,
ranked_state.unit_id,
ranked_state.type,
ranked_state.state,
ranked_state.date,
pu.visible
FROM ranked_state
LEFT JOIN propertyUnits pu
ON ranked_state.property_id = pu.property_id AND pu.visible = 1
WHERE rn = 1
If I explain this query.. First, regarding the rows that meet the given condition(ex: us.type="$name", us.property_id=$propertyID), the rows with the same unit_id are ordered by date.
After then do LEFT JOIN.

I try different options, but I still can't get the result. It still ignores the visible attribute and does not return the last record by date.
Here is my last try:
$query = "SELECT UniEne.id,
UniEne.property_id,
UniEne.unit_id,
UniEne.type,
UniEne.state,
UniEne.date,
propUni.visible
FROM
(SELECT * FROM propertyUnitEnergyStates WHERE type = '$name' AND property_id = $propertyID ORDER BY date DESC) AS UniEne
INNER JOIN (SELECT * FROM propertyUnits WHERE property_id= $propertyID AND visible = 1) as propUni
WHERE UniEne.property_id = $propertyID GROUP BY UniEne.unit_id";
Result is:
But value "state" is not correct. The last inserted have in unit_id(1) value 7000..

Related

I want the highest value to be on the top of the list

So I have this query and display the value, the 'time' is integer, it is often updated by clicking and when it is updated I want the highest value si on the top of the list when page is refresh, but it's not, I wonder if the grouping affects the query?
$sql= "select * FROM message
where userid_to = '$UserLoggedIn' || userid_from = '$UserLoggedIn'
group by conversation_id
ORDER BY time DESC";
I think you should be doing the aggregation on conversations inside a subquery to find the most recent time for each conversation. Then join back to your message table to obtain the full message record. I'm not sure what went wrong with your ordering, but your current query is not deterministic.
SELECT m1.*
FROM message m1
INNER JOIN
(
SELECT conversation_id, MAX(time) AS max_time
FROM message
WHERE userid_to = '$UserLoggedIn' OR userid_from = '$UserLoggedIn'
GROUP BY conversation_id
) m2
ON m1.conversation_id = m2.conversation_id AND
m1.time = m2.max_time
ORDER BY
m1.time DESC;
I would try doing it this way:
SELECT *, MAX(time) as time
FROM message
WHERE userid_to = '$UserLoggedIn' OR userid_from = '$UserLoggedIn'
GROUP BY conversation_id;

Multiple PHP subqueries not giving desired result

I have a MySQL table from which I want to extract attendance information(Student Id, course/subject for attendance, date range,whether the student was present or not). I have written the following query:
SELECT
COUNT(a_id),
(
SELECT COUNT(*) FROM attendance
WHERE state = 'present'
AND `dater` BETWEEN '$a' AND '$b'
) AS Count,
stud_id
FROM attendance
WHERE
stud_id =(SELECT id FROM users WHERE NAME = '$stud')
Which is giving me the correct results, but when I change the student,its not giving me the correct count for the days recorded for present. Not mention that I have not yet added the course parameter into the query
The MySQL table is as follows:
I need help for the query to return the desired results(Count the accurate days present for each student, as well as adding the course parameter into the query so that the query will look for attendance records for a specific course, for a specific student, for a specified date range).
Looks like you want to seperate your queries:
Select (select count(*) from <database>.attendance where state = 'present' AND (dater between '$a' and '$b') AND name=(SELECT id FROM users WHERE NAME = '$stud')) as present, (select count(*) from <database>.attendance where state = 'absent' AND (dater between '$a' and '$b') AND name=(SELECT id FROM users WHERE NAME = '$stud')) as absent from <database>.attendance WHERE stud_id =(SELECT id FROM users WHERE NAME = '$stud');
try this :)
Resolved it using JOIN as follows:
SELECT u.id, a.stud_id, a.course_id, count(*) FROM attendance a
JOIN users u ON u.id=a.stud_id
JOIN courses c ON c.c_id=a.course_id
WHERE a.state='present' and dater between '2017-09-01' and '2017-09-14'
GROUP BY a.stud_id, a.course_id;
Thanks for your help.

Sorting data from MySQL by SUM with Grouping By - not working properly

I have a problem with mysql - i'm kind new to it, byt looking to improve my skills :)
Have a code like this:
if($where > 0) $query = mysql_query("SELECT img.*, user.user as owner_name, cat.name as cat_name FROM tentego_img AS img LEFT JOIN tablicacms_users AS user ON user.id = img.owner LEFT JOIN tentego_img_cat AS cat ON cat.id = img.cat WHERE img.`is_waiting` LIKE ".$where.$cat." INNER JOIN tentego_img_vote ON tentego_img.id = tentego_img_vote.object_id GROUP BY tentego_img_vote.object_id ORDER BY SUM ( (CASE WHEN tentego_img_vote.vote = '0' THEN '-1' ELSE '1' END) ) DESC LIMIT ".$page.",".$objPerPage);
I need to make sorting by number of votes, sorted descending.
Still it makes results sorted by it own way.
In table I have rows:
ID - vote id for table purpose
object_id- id of object joined with another table to show results.
User ID - user id
Vote - where values are 0 for dislike and 1 for like (so -1 for 0, and +1 for 1)
So, as I understand i need to sum up all records for each of unique object_id, then sort by sum of vote values of each.
This code worked before my script provider decide to upgrade it, so right now i dont know how to fix it :(

Getting all id's of group with recent record in mysql

I have users with different group code in my MySQL database. I am saving their latitude and longitude in database according to their current positions.
Problem is I am not able to get their recent records according to their group code.
I have tried this
SELECT * FROM tracklatlong WHERE id IN (SELECT MAX( id ) FROM
tracklatlong GROUP BY 'track_CfiUw');
but i am only getting last record of this track_CfiUw group code.
i want result like below
Your query should be like,
SELECT tl1.id,tl1.admin_id,tl1.name,tl1.groupcode
FROM tracklatlong tl1
LEFT JOIN tracklatlong tl2 ON (tl1.name = tl2.name AND tl1.id < tl2.id)
WHERE tl2.id IS NULL AND tl1.groupcode = 'track_CfiUw';
But instead you are grouping it by group_code value.

SELECT from two tables WHERE different columns in each table equal $id ORDER BY common column (PHP/MySQL)

I'm trying to SELECT from two tables and ORDER BY date (a column they both have). One table (tableA) has a column called "A" and the other table (tableB) has a column called "B", I use array_key_exists() to differentiate between the two (If "A" key exists, I run the array through FunctionA(), if "B" key exists, I run the array through FunctionB()). I only need the 20 latest (date wise) entries. I need the SQL Query to accomplish this.
I already know a reply will be "if they're similarly structured, then you should just use a single table", but I don't want to do that because tableA is drastically different from tableB (a lot more columns in tableA), and using a single table to store the data would result in a LOT of empty columns for entries formatted for tableB, not to mention it'd be a very ugly looking table format due to tableB not needing the majority of tableA's columns).
I just want to display data from both tables in an ordered (by date) fashion, and in one single stream.
I need to SELECT WHERE tableA.poster_id = $id and tableB.receiver_id = $id by the way.
SOLUTION:
I'm updating this just in case anyone else with the same dilemma comes along. After implementing the SQL query that #Erik A. Brandstadmoen had graciously given me, this is basically what my code ended up as:
$MySQL->SQL("SELECT * FROM
(SELECT A.id AS id, A.date AS date, 'tableA' AS source
FROM tableA A WHERE A.poster_id = $id
UNION
SELECT B.id AS id, B.date AS date, 'tableB' AS source
FROM tableB B WHERE B.receiver_id = $id) AS T
ORDER BY T.date DESC LIMIT 0, 20");
$GetStream = array();
$i = 0;
while ($row = mysql_fetch_array($MySQL->Result))
{
$GetStream[$i]['id'] = $row['id'];
$GetStream[$i]['date']=$row['date'];
$GetStream[$i]['source'] = $row['source'];
$i++;
}
*** later on down the code ***
$i = 0;
while ($i<count($GetStream))
{
if ($GetStream[$i]['source'] == "tableA")
{
FunctionA($GetStream[$i]);
}
else
{
FunctionB($GetStream[$i]);
}
$i++;
}
Try using UNION:
SELECT * FROM (
SELECT A.col1 AS x, A.col2 As y, A.col3 AS date FROM tableA A
WHERE tableA.poster_id = $id
UNION
SELECT B.colA AS x, B.colB AS y, B.colC AS date FROM tableB B
WHERE tableB.receiver_id = $id
)
ORDER BY date DESC
LIMIT 0, 20
OR, IF you would like to keep duplicates between tableA and tableB, use UNION ALL instead.
EDIT, according to your comments, I understand that you need a column indicating which table the row is from. You can just add a static column in the select, like this:
SELECT * FROM (
SELECT A.col1 AS x, A.col2 As y, A.col3 AS date, 'A' as source FROM tableA A
WHERE tableA.poster_id = $id
UNION
SELECT B.colA AS x, B.colB AS y, B.colC AS date, 'B' as source FROM tableB B
WHERE tableB.receiver_id = $id
)
ORDER BY date DESC
LIMIT 0, 20
This gives you a nice table on the following form:
x y date source
=========================
(v1) (v2) (d1) 'A'
(v3) (v4) (d2) 'B'
(v1) (v2) (d3) 'B'
(v3) (v4) (d4) 'A'
That does what you want, doesn't it? It's a bit difficult understanding what you are really trying to achieve with this...

Categories