How to show all the other results after Group By - php

I "Group By" all the deals in my database by store. How can I show all the other deals who where not grouped after the query?
This is the query I'm using:
$query = mysql_query("SELECT * FROM deals WHERE DATE_FORMAT(expiration_date,'%Y-%m-%d %H:%i:%s') >= NOW() $cat ORDER BY deal_id ASC") or die(mysql_error());

On a slightly different note, a query like this to retrieve records based on date is bad.
SELECT *
FROM deals
WHERE DATE_FORMAT(expiration_date,'%Y-%m-%d %H:%i:%s') >= NOW()
AND cat1 LIKE '%$geef%'
ORDER BY deal_id ASC
What is the format of your expiration date? Given that you are passing it to DATE_FORMAT I would assume it is a DATE or DATETIME type. Wrapping your expiration_date in DATE_FORMAT means the optimiser cannot use an index on that field, forcing a full table scan. This is bad news!
You will get the same result with the DATE_FORMAT removed -
SELECT *
FROM deals
WHERE expiration_date >= NOW()
AND cat1 LIKE '%$geef%'
ORDER BY deal_id ASC
and now the optimiser will be able to use an index that contains expiration_date as the first field in the index.
The fact that you have a field called cat1 leads me to think that you may have other category fields. Again, this is bad news. Repeating groups across columns are not your friend. They make all sorts of things harder than they need to be and they are inefficient. Have a read of this article on First Normal Form.

Related

Parse SQL results by month using timestamp MySQL

I have a small problem with SQL. I need to select ID of rows and group them into arrays (or something) BY MONTH? I have a timestamp column there.
So if there are rows like this:
ID Timestamp
1 blalba(1.10.2017)
2 blabla(2.10.2017)
3 blabla(1.5.1996)
The output would be like
array(
[5.1996] => array([3]),
[10.2017] => array([1,2]);
)
(Or something like this).
Is this possible in PHP using some PHP libraries? Or Do I have to implement my own class doing this?
You are probably looking for group_concat
select group_concat(id separator ', ') as myList,
DATE_FORMAT(Timestamp, '%Y-%m') from <YOUR_TABLE>
GROUP BY DATE_FORMAT(Timestamp, '%Y-%m');
Well you might be handle this on the MySQL side by ordering by month/year:
SELECT
ID, Timestamp
FROM yourTable
ORDER BY
DATE_FORMAT(Timestamp, '%Y-%m');
This query would return a result set to PHP which would be ordered such that all records in the same month and year would be clustered together. You could then just iterate this result set and process the records as you want.

Selecting multiple tables and displaying them ordered by datetime column

I want to display the logs to recent activities page ordered by date. Now I was trying to execute this to my mysql
"SELECT * FROM tracking_log.editlog, tracking_log.deletelog, tracking_log.loginlog, tracking_log.logoutlog ORDER BY time ASC";
but it always says
Column 'time' in order clause is ambiguous
all of the tables have a time column, format by datetime (0000-00-00 00:00:00)
How am I going to fetch them ordered by time?
Thanks in advance!
By which table's time column you want to order?
Assuming you want to order the result set by tracking_log.editlog.time column then the query would look like below:
SELECT
*
FROM tracking_log.editlog, tracking_log.deletelog,
tracking_log.loginlog, tracking_log.logoutlog
ORDER BY tracking_log.editlog.time ASC;
Just in case if all of the time columns in the respective table don't contain NOT NULL values at the same time then you need to use COALESCE I guess.
Query using COALESCE
SELECT
*
FROM tracking_log.editlog, tracking_log.deletelog,
tracking_log.loginlog, tracking_log.logoutlog
ORDER BY
COALESCE(tracking_log.editlog.time , tracking_log.deletelog.time, tracking_log.loginlog.time,tracking_log.logoutlog.time) ASC;
'tracking_log' is your database name, and you're selecting multiple tables from that database, so you need to specify from which table you want to order 'time' by:
select * from tracking_log.editlog, tracking_log.deletelog ORDER BY tracking_log.editlog.time ASC
or whichever table from your database you want to use 'time' from. This will fix the error but won't return any results because you have multiple tables in a SELECT clause without anything relating them together.
You'll need to specify some common columns on which you want to return results rather than getting the wildcard and then UNION the tables to aggregate the results. For example, if you have common columns userID, description and time in all your tables, you could do the following:
(SELECT userID, description, time FROM tracking_log.editlog)
UNION
(SELECT userID, description, time FROM tracking_log.deletelog)
ORDER BY time

MySQL - Sort multiple columns together; not first, then second, etc

I have a table with 4 different date columns (date_created, date_saved, date_published, date_deleted), and I'm trying to do a "most recent updates" query, effectively taking any of those 4 dates into consideration and sorting by the most recent dates desc. Normally you'd do:
date_created DESC, date_saved DESC, date_published DESC, date_deleted DESC
But I don't want it to give more importance to date_created than date_deleted. All the date fields are an "update" so they should all be treated equally in the sorting.
I'd rather not select all the results in the whole database and then use PHP to sort and limit for resources sake, so, is there a way sort DESC on all of those 4 fields, while treating them all as equal importance?
simply do:
ORDER BY GREATEST(date_created, date_saved, date_published, date_deleted)

SQL tricky order by

i'm trying to order a returned set, but i'm having a hard time getting it to order properly.
i'm selecting fields, and each field has a date_updated and a date_added.
when the field is added, the date_updated is null, until there is an update, which it then assigns the current date.
i need to order my list by having the most recent entries be on the BOTTOM, and oldest on the top. so if a item is added, it should go directly to the bottom. is there a way to join all the date fields together, and then just sort by oldest to newest, disregarding update or added?
this may sound kind of confusing, but i've already tried numerous combinations of ORDER BY date_added DESC, date_updated ASC, and things like that, but it's not doing what I need it to do. i get the top portion ordered by date_added and then under that is a separate ordering for date_updated...
any input would be really helpful here...
try
order by coalesce(date_updated, date_added)
COALESCE DOC
You can try a CASE statement
SELECT
firstname,
lastname,
date_added,
date_updated,
CASE date_updated IS NULL
THEN date_added
ELSE date_updated
END CASE AS order_date
FROM mytable
ORDER BY order_date DESC
What this does is it checks if date_updated is null and then puts in the new column the value of date_added. If not, it puts the date_updated. The new column is called order_date and is used for sorting.
You can also add the CASE statement in the ORDER BY clause but that might slow your query down since it has to do the concatenation on the index vs. when constructing the data. Although not conclusive, I have found a slight performance gain if the CASE is used in the SELECT vs. the ORDER BY.
Use CASE in Order By Clause.
ORDER BY CASE WHEN date_updated IS NULL
THEN 0
ELSE 1
END DESC, date_added DESC
Order by IsNull(DateUpdated,DateAdded)
would be one way

Join two tables, then Order By date, BUT combining both tables

Alright, I'm trying to figure out why I can't understand how to do this well...
I have two tables:
invoices:
id
userID
amount
date
payments:
id
userID
amount
date
So, the goal here is to join both tables, where the userID matches whatever I want it to be - and then return everything ordered by date (most recent at the top). However, because there is a date field in each of the tables, I'm not sure how MySQL will handle things... will is sort by both dates automatically? Here's what I was thinking...
"SELECT DISTINCT *
FROM invoices,payments
WHERE {$userID} = invoice.userID
OR {$userID} = payments.userID
ORDER BY date DESC";
But, it's starting to become clear to me that maybe this isn't even the right use of a join command... maybe I need to just get all data on each table alone, then try to sort it somehow with PHP? If that's the better method, what's a good way to do this type of DATE sort while keeping all row data in tact?
I should add, the TIME inside the unix timestamp (that's how "date" is stored) is NOT negligible - it should sort by the date and time.
Thanks all...
If the columns of both tables are the same, you can use a UNION
SELECT X.*
FROM ( SELECT `id`,
`userID`,
'INVOICE' AS PTYPE
`amount`,
`date`
FROM `invoices`
WHERE {$userID} = userID
UNION
SELECT `id`,
`userID`,
'PAYMENT' AS PTYPE
`amount`,
`date`
FROM `payments`
WHERE {$userID} = userID
) X
ORDER BY X.`date`
EDIT
Read the relevant section of the MySQL manual on UNIONS. There are other ways of phrasing this, but this is my preferred style - it should be clear to anybody reading that the ORDER BY clause applies to the result of both sides of the UNION. A carelessly written UNION - even with an ORDER BY - may still leave the final resultset in indeterminate order.
The purpose of the PTYPE is that this query returns an extra column called PTYPE, that indicates whether each individual row is an INVOICE or a PAYMENT... ie. which of the two tables it comes from. It's not mandatory, but can often be useful within a union
Because you have two identical fields named date, MySQL will not know which one you're trying to order by.
"SELECT DISTINCT *
FROM invoices,payments
WHERE {$userID} = invoice.userID
OR {$userID} = payments.userID
ORDER BY invoices.date, payments.date DESC";
This would sort on the invoice date, then the payment date - if that's what you are trying to find out
If your data tipe is Date, Timestamp, or anything related, the SGBD will order it properly. If that was what you've asked.
But if the datatype is String, even when dates is store, it will not sort the way you want.

Categories